dagger-2 – Dagger 2依赖是否可以不注射?

有没有办法告诉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]

因此,虽然错误消息有点误导,但这种技术是整洁有效的.

点赞