Dagger2:注入具有组件本身的模块提供的实现类

时间:2015-05-31 08:18:01

标签: java android dagger-2

考虑到模块都是通过=IFERROR(INDIRECT("'Student Needs'!"&CHAR(72+IFERROR(MATCH("HR "&E$2,ARRAYFORMULA(REGEXEXTRACT(INDIRECT("'Student Needs'!I"&ROW(VLOOKUP($A3,'Student Needs'!$A$1:$B,2,false))&":N"&ROW(VLOOKUP($A3,'Student Needs'!$A$1:$B,2,false))),"[A-Z ]+[0-9]")),0),MATCH($C3,ARRAYFORMULA(REGEXEXTRACT(INDIRECT("'Student Needs'!I"&ROW(VLOOKUP($A3,'Student Needs'!$A$1:$B,2,false))&":N"&ROW(VLOOKUP($A3,'Student Needs'!$A$1:$B,2,false))),"[A-Z]+")),0)))&5)) 的Dagger1规范在彼此之间共享,您可以通过构造函数参数接收complete=false, library=true方法提供的元素,如此。

@Provides

但是,您也可以只指定一个包含组件图的依赖项(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

这样,您只需要依赖演示者的对象图,而不必混淆构造函数参数。

哪一个是更好的方法?

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

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);
    }
}

然后

@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;
    }
}

问题:这样,当注入器准备好时,所有依赖项都是从应用程序的组件提供的,而不是通过构造函数。但这是一个好方法吗?从长远来看,有什么警告吗?

EDIT2:我这里有注射器,但是非常糟糕。

我所拥有的in my other project was better constructed

2 个答案:

答案 0 :(得分:1)

使用构造函数注入方法,您只使用标准JSR-330注释注释类,因此:

  • 代码与您正在使用的具体依赖注入库分离。如果你需要回头,让我们说一个旧版本的匕首,只有你的模块和组件定义必须改变,而不是你的核心类。

  • 您的课程不需要了解它们的生成方式。明天您可能根据范围使用不同的组件,或者您可能希望将组件从演示者类中取出。因此,你的核心课程不应该改变。

  • 它使您的模块测试更容易。无需通过应用程序运行代码生成或替换组件实例。只需在构造函数中直接注入模拟或测试模块,即可完成。

仅在模块的生命周期不受控制的情况下才应使用现场和方法注入。这将是Android环境中的活动或片段的情况。在该用例之外,这些方法只是问题的根源。

答案 1 :(得分:0)

如果通过组件/模块提供依赖项,则在创建依赖项时组件将始终存在。因此,您可以在其构造函数中调用字段注入。它不能简单。