Dagger 2依赖关系是否不可注入? [英] Can a Dagger 2 dependency be non-injectable?
问题描述
是否可以告诉Dagger 2如何提供某些东西,但不允许其注入?
Is there a way to tell Dagger 2 how to provide something, but not allow it to be injected?
说我想注入 Qux
。 Qux
需要 Foo
和 Bar
:
Say I want to inject a Qux
. A Qux
requires a Foo
and 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);
}
但是如果我不想 Foo
和 Bar
是否可以注射?暴露它们可能会破坏 Qux
的封装,或者它们是某种工厂,我只想要 Qux
可以访问。
But what if I don't want Foo
and Bar
to be injectable? Perhaps exposing them would break the encapsulation of the Qux
, or perhaps they're factories of some kind that I only want the Qux
to have access to.
我想到了几种方法可以实现:
I've thought of a couple ways I could achieve this:
- 如果其他提供程序需要
Foo
单例,则可以将其设为类成员。但是,如果Foo
有其自己的多个依存关系,则会变得混乱。 - 如果
Bar $其他提供程序不需要c $ c>单例,我可以在
Qux
提供程序内创建实例。但是,如果Qux
具有这样的依赖关系,这将变得很混乱。
- If the
Foo
singleton is needed by other providers, I could make it a class member. But this would get messy ifFoo
has several dependencies of its own. - If the
Bar
singleton is not needed by any other providers, I could create the instance inside theQux
provider. But this would get messy ifQux
has several dependencies like that.
都不这些解决方案似乎非常优雅或Daggery。还有另一种方法吗?
Neither of these solutions seem very elegant or Daggery. Is there another way?
推荐答案
实现您要尝试的操作的最简单方法是定义一个程序包专用的限定符
The easiest way to achieve what you're trying to do is to define a package-private qualifier.
package my.pkg;
@Qualifier
@Retention(RUNTIME)
@interface ForMyPackage {}
然后,将其用于绑定Foo和Bar:
Then, use that for your bindings for Foo and 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如果可以访问限定符。
That way, you can only request that those versions of Foo and Bar be injected if you have access to the qualifier.
如果所有这些绑定都在单个模块中,则甚至可以在模块中使用私有的嵌套限定符。
If all of these bindings are in a single module, you can even use a private, nested qualifier in the module.
由问问者编辑:
我尝试了最后一个建议。
I tried the last suggestion.
@Qualifier
@Retention(RUNTIME)
private @interface NoInject {}
@Provides
@Singleton
@NoInject
Foo foo() { return new Foo(); }
尝试注入 Foo
会导致编译时错误,根据需要:
Attempting to inject a Foo
causes a compile-time error, as desired:
错误:(15,6)Gradle:错误:com.mydomain.myapp.Foo不能为无需@Inject构造函数或@ Provides-或@ Produces-注释方法提供。
com.mydomain.myapp.MyActivity.foo
[注入的字段类型:com.mydomain.myapp.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]
因此,尽管错误消息有点让人误解,但这种技术既简洁又有效。
So while the error message is a bit misleading, this technique is neat and effective.
这篇关于Dagger 2依赖关系是否不可注入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!