我有一些类需要注入特定对象(让我们将其命名为ToInject
)。
问题是我无法从单独的模块中提供ToInject
:
@Module(injects={OneActivity.class})
public class OneActivityModule {
@Provides
public ToInject provideToInject(){
return new ToInject(...)
}
}
@Module(injects={TwoActivity.class})
public class TwoActivityModule {
@Provides
public ToInject provideToInject(){
return new ToInject(...)
}
}
创建ObjectGraph时出现此异常:
Caused by: java.lang.IllegalArgumentException: TwoActivityModule: Duplicate:
com.example.test.OneActivityModule$$ModuleAdapter$ProvideToInjectProvidesAdapter[key=com.example.test.ToInject method=com.example.test.OneActivityModule.provideToInject()]
com.example.test.TwoActivityModule$$ModuleAdapter$ProvideToInjectProvidesAdapter[key=com.example.test.ToInject method=com.example.test.TwoActivityModule.provideToInject()]
at dagger.ObjectGraph$DaggerObjectGraph.makeGraph(ObjectGraph.java:187)
at dagger.ObjectGraph$DaggerObjectGraph.access$000(ObjectGraph.java:138)
at dagger.ObjectGraph.create(ObjectGraph.java:129)
我知道我可以将ToInject
个提供者移动到一个模块中,然后使用限定符来制作独特的,但为什么不能这样做呢?为每个模块指定了injects
,是否也使这些提供商也独一无二?
有什么建议吗?
更新
我考虑过这个问题,真正的问题是我想根据Activity获取它来配置ToInject
对象。 ToInject
实际上是一个抽象类(上面的代码片段仅使用"而不是抽象"类仅用于示例)。
我的结论是我应该只为ToInject
使用一个提供程序,因此我可以通过更改单行代码来更改实现。但是我仍然需要根据Activity获取它来配置ToInject
对象。
所以主要问题是Dagger是否可以实现这一点,还是我必须将配置传递给每个Activity,并手动设置它?
此情况下的配置是ID(String
),要配置的对象(本例中为ToInject
)是显示广告横幅的片段。我想尽可能地将它与Activity分开,所以我可以在其他项目中重用它。
答案 0 :(得分:0)
我找到了足够的解决方案。
这是一个负责提供摘要ToInject
的实现的库。
@Module(library=true)
public class ProviderModule {
@Provides
public ToInject provideToInject(){
return new ToInjectConcrete1();
}
}
我可以通过以下方式创建特定于Activity的模块。正如您所看到的,此ToInject
提供程序方法具有ToInject
参数,该参数实际上是由上面的库提供的。在我得到它之后,我可以进行特定于我的Activity的进一步配置。
@Module(injects = OneActivity.class, includes = ProviderModule.class)
public class OneActivityModule {
@Provides
@Named("one")
public ToInject provideToInject(ToInject toInject) {
toInject.text = "overridden by one";
return toInject;
}
}
关键是使用限定符(在本例中为@Named
限定符)。
注意:强>
我的问题的根源在于我假设提供者方法在单独的模块中(定义了injects
)是唯一的。现在我知道injects
用于编译时验证,并且与提供者的单一性无关。具有相同返回类型的提供者可以使用限定符(例如@Named
)使其唯一,就像我在此解决方案中所做的那样。