有没有办法告诉 Dagger 2 如何提供某些东西,但不允许它被注入?
假设我想注入一个Qux. AQux需要 aFoo和 a 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);
}
Run Code Online (Sandbox Code Playgroud)
但如果我不想注射怎么Foo办Bar?也许暴露它们会破坏 的封装,或者它们可能是我只想访问的Qux某种工厂。Qux
我想到了几种可以实现这一目标的方法:
Foo其他提供者需要该单例,我可以将其设为类成员。Foo但如果它自己有几个依赖项,这会变得混乱。Bar任何其他提供程序不需要该单例,我可以在Qux提供程序内创建实例。但如果Qux有多个这样的依赖项,这会变得混乱。这些解决方案看起来都不是非常优雅或危险。还有别的办法吗?
实现您想要做的事情的最简单方法是定义一个包私有限定符。
package my.pkg;
@Qualifier
@Retention(RUNTIME)
@interface ForMyPackage {}
Run Code Online (Sandbox Code Playgroud)
然后,将其用于 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);
}
Run Code Online (Sandbox Code Playgroud)
这样,如果您有权访问限定符,则只能请求注入 Foo 和 Bar 的这些版本。
如果所有这些绑定都在单个模块中,您甚至可以在模块中使用私有的嵌套限定符。
提问者编辑:
我尝试了最后一个建议。
@Qualifier
@Retention(RUNTIME)
private @interface NoInject {}
@Provides
@Singleton
@NoInject
Foo foo() { return new Foo(); }
Run Code Online (Sandbox Code Playgroud)
根据需要,尝试注入 aFoo会导致编译时错误:
错误:(15, 6) Gradle:错误:如果没有 @Inject 构造函数或从 @Provides- 或 @Produces- 注解的方法,则无法提供 com.mydomain.myapp.Foo。com.mydomain.myapp.MyActivity.foo [注入字段类型:com.mydomain.myapp.Foo foo]
因此,虽然错误消息有点误导,但这种技术简洁有效。
| 归档时间: |
|
| 查看次数: |
253 次 |
| 最近记录: |