有没有办法告诉Dagger 2如何提供某些东西,但不允许它被注入?
说我想要注入一个Qux. Qux需要Foo和Bar:
@Provides
@Singleton
Foo foo() {
return new Foo();
}
@Provides
@Singleton
Bar bar() {
return new Bar();
}
@Provides
@Singleton
Qux qux(final Foo foo, final Bar bar) {
return new Qux(foo, bar);
}
但是如果我不想要Foo和Bar可以注射呢?暴露它们可能会破坏Qux的封装,或者它们可能是我只想让Qux访问的某种工厂.
我想过几种方法可以达到这个目的:
>如果其他提供商需要Foo单例,我可以使其成为类成员.但如果Foo有自己的几个依赖关系,这将变得混乱.
>如果任何其他提供程序不需要Bar单例,我可以在Qux提供程序中创建实例.但是如果Qux有这样的几个依赖关系,这会变得混乱.
这些解决方案似乎都不是很优雅或者是Daggery.还有另外一种方法吗?
最佳答案 实现您要做的事情的最简单方法是定义一个包私有限定符.
package my.pkg;
@Qualifier
@Retention(RUNTIME)
@interface ForMyPackage {}
然后,将它用于Foo和Bar的绑定:
@Provides
@Singleton
@ForMyPackage
Foo foo() {
return new Foo();
}
@Provides
@Singleton
@ForMyPackage
Bar bar() {
return new Bar();
}
@Provides
@Singleton
Qux qux(final @ForMyPackage Foo foo, final @ForMyPackage Bar bar) {
return new Qux(foo, bar);
}
这样,如果您有权访问限定符,则只能请求注入那些版本的Foo和Bar.
如果所有这些绑定都在一个模块中,您甚至可以在模块中使用私有的嵌套限定符.
由提问者编辑:
我尝试了最后一个建议.
@Qualifier
@Retention(RUNTIME)
private @interface NoInject {}
@Provides
@Singleton
@NoInject
Foo foo() { return new Foo(); }
尝试注入Foo会导致编译时错误,如下所示:
Error:(15, 6) Gradle: error: com.mydomain.myapp.Foo cannot be provided without an @Inject constructor or from an @Provides- or @Produces-annotated method.
com.mydomain.myapp.MyActivity.foo
[injected field of type: com.mydomain.myapp.Foo foo]
因此,虽然错误消息有点误导,但这种技术是整洁有效的.