Dagger2:注射用组件本身模块提供的实现类 [英] Dagger2: Injecting implementation classes provided by modules with component itself

查看:224
本文介绍了Dagger2:注射用组件本身模块提供的实现类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑到模块都是当中的一个,另外一个通过的Dagger1规范共享完整=假,图书馆= TRUE ,可以接收由<$ C $提供的元素C> @Provides 通过构造函数的参数的方法,像这样。

Considering modules are all shared among one-another through the Dagger1 specification of complete=false, library=true, you can receive the elements provided by the @Provides methods through a constructor parameter, like so.

public class GetUserForUsernameTaskImpl
        implements GetUserForUsernameTask {
    public static final String TAG = GetUserForUsernameTaskImpl.class.getSimpleName();

    private Realm realm;
    private UserRepository userRepository;

    public GetUserForUsernameTaskImpl(Realm realm, UserRepository userRepository) {
        this.realm = realm;
        this.userRepository = userRepository;
    }

    @Override
    public RealmResults<UserRLM> getUsers() {
        try {
            RealmResults<UserRLM> users = userRepository.findAll(realm);
    ...
}

@Module(includes = {RepositoryModule.class, RealmModule.class})
public class DatabaseTaskModule {
    @Provides
    public GetUsersDatabaseTask getUsersDatabaseTask(Realm realm, UserRepository userRepository) {
        return new GetUsersDatabaseTaskImpl(realm, userRepository);
    }
}

不过,您也只能指定一个依赖(即 presenter CustomApplication 实例)的持有组件图,并使用该组件图形注入您的实现类。

However, you could also specify only one dependency (the Presenter or the CustomApplication instance) that holds the component graph, and use that component graph to inject your implementation classes.

public class GetUserForUsernameTaskImpl
        implements GetUserForUsernameTask {
    public static final String TAG = GetUserForUsernameTaskImpl.class.getSimpleName();

    @Inject
    public Realm realm;
    @Inject
    public UserRepository userRepository;

    protected Presenter presenter;
    private boolean isInjected = false;

    public GetUserForUsernameTaskImpl(Presenter presenter) {
        this.presenter = presenter;
    }

    @Override
    public RealmResults<UserRLM> getUsers() {
        if(!isInjected) {
            presenter.getPresenterComponent().inject(this);
            isInjected = true;
        }
        try {
            RealmResults<UserRLM> users = userRepository.findAll(realm);
            ...
    }
}

@Module(includes = {PresenterModule.class})
public class DatabaseTaskModule {
    @Provides
    public GetUsersDatabaseTask getUsersDatabaseTask(Presenter presenter) {
        return new GetUsersDatabaseTaskImpl(presenter);
    }
}

和的方式,你只需要依赖于presenter的对象图,而不必惹构造函数的参数。

And that way, you'd only have to depend on the presenter's object graph, and not have to mess with constructor parameters.

哪一个是更好的方法?

编辑::一种更加清晰和具体的例子我有一个不太好重构项目如下:

A clearer and concrete example I have in a not-too-well refactored project is the following:

@Module(includes = {ContextModule.class})
public class ClientAuthModule {
    @Provides
    public ClientAuthAuthenticator clientAuthAuthenticator(CustomApplication customApplication) {
        return new ClientAuthAuthenticator(customApplication);
    }
}

然后

public class CustomApplication
        extends Application {
    public static class InjectorInitializedEvent {
    }

    public static class InjectorInitializedEventProducer {
        @Produce
        public InjectorInitializedEvent produceEvent() {
            return new InjectorInitializedEvent();
        }
    }

    private ApplicationComponent applicationComponent;

    @Override
    public void onCreate() {
        super.onCreate();
        applicationComponent = Injector.INSTANCE.initializeApplicationComponent();
        SingletonBus.INSTANCE.getBus().post(new InjectorInitializedEvent());
        SingletonBus.INSTANCE.getBus().register(new InjectorInitializedEventProducer()); //OTTO bus, event producer
    }

    public ApplicationComponent getApplicationComponent() {
        return this.applicationComponent;
    }
}

然后

public class ClientAuthAuthenticator {
    private CustomApplication customApplication;

    @Inject
    public PEMConverter pemConverter;
    @Inject
    public KeyPairCreator keyPairCreator;
    @Inject
    public PKCS10CsrCreator pkcs10CsrCreator;
    @Inject
    public KeyPairReader keyPairReader;
    //...

    public ClientAuthAuthenticator(CustomApplication customApplication) {
        this.customApplication = customApplication;
        SingletonBus.INSTANCE.getBus().register(this);
    }

    @Subscribe
    public void onInjectorInitializedEvent(CustomApplication.InjectorInitializedEvent e) {
        customApplication.getApplicationComponent().inject(this);
        SingletonBus.INSTANCE.getBus().unregister(this);
    }

    ...

的问题:这样,从应用程序的组件提供所有的依赖关系,当注射器准备就绪,而不是通过构造函数。但是,这是一个好方法?现就长期来看有什么注意事项?

The question: This way, all dependencies are provided from the application's component when the injector is ready, rather than through the constructor. But is this a good approach? Are there any caveats on the long-run?

EDIT2:添加喷油器类作为每个请求

public enum Injector {
    INSTANCE;

    private ApplicationComponent applicationComponent;

    ApplicationComponent initializeApplicationComponent() {
        ClientAuthModule clientAuthModule = new ClientAuthModule();
        ServerCommunicationModule serverCommunicationModule = new ServerCommunicationModule();
        CertUtilModule certUtilModule = new CertUtilModule();
        EmmUtilsModule emmUtilsModule = new EmmUtilsModule();
        EncryptUtilsModule encryptUtilsModule = new EncryptUtilsModule();
        OtherUtilsModule otherUtilsModule = new OtherUtilsModule();
        SerializerModule serializerModule = new SerializerModule();
        ContextModule contextModule = new ContextModule();
        LogicModule logicModule = new LogicModule();
        UtilsComponent utilsComponent = DaggerUtilsComponent.builder()
                .emmUtilsModule(emmUtilsModule)
                .encryptUtilsModule(encryptUtilsModule)
                .otherUtilsModule(otherUtilsModule)
                .certUtilModule(certUtilModule)
                .contextModule(contextModule)
                .clientAuthModule(clientAuthModule)
                .serializerModule(serializerModule)
                .build();
        NetworkingComponent networkingComponent = DaggerNetworkingComponent.builder()
                .clientAuthModule(clientAuthModule)
                .contextModule(contextModule)
                .otherUtilsModule(otherUtilsModule)
                .serverCommunicationModule(serverCommunicationModule)
                .build();
        applicationComponent = DaggerApplicationComponent.builder()
                .networkingComponent(networkingComponent)
                .utilsComponent(utilsComponent)
                .contextModule(contextModule)
                .logicModule(logicModule)
                .build();
        return applicationComponent;
    }

    public ApplicationComponent getApplicationComponent() {
        return applicationComponent;
    }
}

在我有<一个href=\"http://stackoverflow.com/questions/31834056/how-do-you-organise-your-dagger-2-modules-and-components/31835913#31835913\">in我的其他项目,更好地构建。

推荐答案

如果你的依赖是通过组件/模块提供,则该组件将永远被创建的依赖时存在。所以,你可以调用字段注入在其构造。它不能比简单

If your dependency is provided through a component / module, then the component will always exist when the dependency is created. So you can call field injection in its constructor. It can't be simpler than that.

这篇关于Dagger2:注射用组件本身模块提供的实现类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆