My dagger configuration for an android project that i'm working on: Note: I've provided all the needed @Component, @Module, @Provides annotations wherever needed.
MainActivity {
@Inject A a;
@Inject B b;
onCreate(){
ComponentX.inject(this);
ComponentY.inject(this);
}
}
ComponentX-> ModuleA ->providerA
ComponentY -> ModuleB -> providerB
As you can see, these are two completely independent components not related to each other in anyway except for at the point of injection.
During compilation I get the following error:
In file A.java
error: B cannot be provided without an @Provides- or @Produces-annotated method.
MainActivity.b
[injected field of type: B b]
Am I mistaken in thinking that multiple components can be used while using dagger 2 or is the application supposed to use one big component which takes care of all the injections?
Can anyone help me understand where i'm going wrong?
答案 0 :(得分:7)
您不必拥有单个组件,有多种方法可以模块化它们,但是您创建或注入值的每个对象必须具有由单个组件提供的所有值。
重构代码的一种方法是让ComponentY依赖于ComponentX,反之亦然,例如。
@Component(dependencies = ComponentX.class)
interface ComponentY {
void inject(MainActivity activity);
}
或者你可以创建第三个组件,比如ComponentZ,如果ComponentX和ComponentY完全相互正交。
@Component(dependencies = {ComponentX.class, ComponentY.class})
interface ComponentZ {
void inject(MainActivity activity);
}
或者您可以重复使用这些模块,例如
@Component(modules = {ModuleA.class, ModuleB.class})
interface ComponentZ {
void inject(MainActivity activity);
}
您决定如何拆分它在很大程度上取决于您的代码结构。如果组件X和Y是可见的但模块不是那么使用组件依赖性,因为它们(和模块依赖性)实际上是组件的实现细节。否则,如果模块可见,则可以简单地重复使用它们。
我不会使用范围,因为它们实际上是用于管理具有不同寿命的对象,例如与特定用户关联的对象,其生命周期是从用户登录到注销时的时间,或特定请求的生命周期。如果他们确实有不同的生命周期,那么您正在考虑使用范围和子组件。
答案 1 :(得分:2)
是应该使用一个大组件的应用程序
有点,你应该在范围内考虑它。对于给定的范围,有一个组件。范围例如是ApplicationScope
,FragmentScope
(保留),ActivityScope
,ViewScope
。对于每个范围,都有一个给定的组件;组件之间不共享范围。
(这实际上意味着如果你想在@ApplicationScope
中拥有全局单例,那么就有一个应用程序范围的组件。如果你想要特定于活动的类,那么你为它创建一个组件activity,取决于应用程序作用域组件。)
请参阅@MyDogTom获取@Subcomponent
注释,但您也可以使用组件依赖关系来创建子范围组件。
@YScope
@Component(dependencies = ComponentX.class, modules=ModuleB.class)
public interface ComponentY extends ComponentX {
B b();
void inject(MainActivity mainActivity);
}
@XScope
@Component(modules=ModuleA.class)
public interface ComponentX{
A a();
}
ComponentY componentY = DaggerComponentY.builder().componentX(componentX).build();
答案 2 :(得分:0)
应用程序应该使用一个需要注意的大组件 所有注射?
您可以使用Subcomponent
。在您的情况下,组件声明将如下所示:
@Subcomponent(modules=ModuleB.class)
public interface ComponentY{
void inject(MainActivity mainActivity);
}
@Component(modules=ModuleA.class)
public interface ComponentX{
ComponentY plus(ModuleB module);
}
ComponentY
创作:creationCompunentY = ComponentX.plus(new ModuleB());
现在在MainActivity
,您只需拨打ComponentY.inject(this);
MainActivity {
@Inject A a;
@Inject B b;
onCreate(){
ComponentY.inject(this);
}
}
有关子组件的更多信息,请参见migration from Dagger1 guide(查看子图部分),Subcomponent JavaDoc和Component JavaDoc(查看子组件部分)。