HashMap классов модернизации с кинжалом

Я новичок в Injection Dependency, и у меня есть сомнения. В моем приложении у меня есть HashMap для хранения встроенных классов (например, кеша) для RetroFit, но теперь я перехожу на DI с Dagger, и я хотел бы знать, как я могу добиться такого же поведения.

Мой код:

private Map<String, Object> restInstances;
public <T> T getRestClient(Class<T> clazz) {
        T client = null;

        if ((client = (T) restInstances.get(clazz.getCanonicalName())) != null) {
            return client;
        }

        client = restAdapter.create(clazz);
        restInstances.put(clazz.getCanonicalName(), client);
        return client;
    }

После запуска с DI мой класс «модуль»:

 @Provides @Singleton
    public JobManager providesJobManager(){
        Configuration config = new Configuration.Builder(app)
                .minConsumerCount(1).maxConsumerCount(3).loadFactor(3).customLogger(new CustomLogger() {
                    private static final String TAG = "JOBS";

                    @Override
                    public boolean isDebugEnabled() {
                        return true;
                    }

                    @Override
                    public void d(String text, Object... args) {
                        Log.d(TAG, String.format(text, args));
                    }

                    @Override
                    public void e(Throwable t, String text, Object... args) {
                        Log.e(TAG, String.format(text, args));
                    }

                    @Override
                    public void e(String text, Object... args) {
                        Log.e(TAG, String.format(text, args));
                    }
                })
                .consumerKeepAlive(120).build();

        return new JobManager(app, config);
    }

    @Provides @Singleton
    public RestAdapter providesRestAdapter()
    {
        restInstances = new HashMap<String, Object>();
        return new RestAdapter.Builder()
                .setEndpoint("http://192.168.0.23:9000/api")
                .setLogLevel(RestAdapter.LogLevel.FULL).build();
    }

Итак, как я могу внедрить этот хеш-кеш в свое приложение?

Спасибо


person Leonardo    schedule 29.07.2014    source источник


Ответы (1)


Вы можете создать класс, единственной целью которого будет предоставление остальных классов интерфейса. Вот интерфейс/реализация

public interface RestApiProvider {
    public <T> T getRestClient(Class<T> clazz);
}

public class RestApiProviderImpl implements RestApiProvider {
    private Map<String, Object> restInstances = new HashMap<String, Object>();
    private RestAdapter restAdapter;

    @Inject
    RestApiProvider(RestAdapter restAdapter) {
        this.restAdapter = restAdapter;
    }

    public <T> T getRestClient(Class<T> clazz) {
        T client = null;

        if ((client = (T) restInstances.get(clazz.getCanonicalName())) != null) {
            return client;
        }

        client = restAdapter.create(clazz);
        restInstances.put(clazz.getCanonicalName(), client);
        return client;
    }

}

В вашем модуле у вас будет

@Provides @Singleton
public RestAdapter providesRestAdapter()
{
    return new RestAdapter.Builder()
            .setEndpoint("http://192.168.0.23:9000/api")
            .setLogLevel(RestAdapter.LogLevel.FULL).build();
}

@Provides @Singleton
public RestApiProvider providesRestApiProvider(RestApiProviderImpl impl) {
    return impl;
}

Это работает так: поставщик RestAdapter из вашего модуля будет использоваться в качестве зависимости в вашем экземпляре RestApiProviderImpl. Теперь везде, где вам нужно получить экземпляр класса RestApi, вам просто нужно внедрить свой RestApiProvider.

@Inject
RestApiProvider restApiProvider;

// Somewhere in your code
RestApiClassOfSomeSort instance = restApiProvider.getRestClient(RestApiClassOfSomeSort.class);
instance.// do what you need!
person Miguel    schedule 30.07.2014
comment
Я не думаю, что смогу сделать public interface RestApiProvider { public T getRestClient(Class<T> clazz); }. Если я не ошибаюсь, это должно быть public interface RestApiProvider<T> { public T getRestClient(Class<T> clazz); }, что сломает этот код, верно? - person Leonardo; 30.07.2014
comment
@LeonardoFerrari на самом деле вы можете определить такой интерфейс, как этот public interface RestApiProvider { public <T> T getRestClient(Class<T> clazz); }, но я пропустил необходимый токен типа, когда публиковал свой ответ, мои извинения за путаницу. Я обновил свой ответ. - person Miguel; 30.07.2014