Can a Dagger 2 dependency be non-injectable?

霸气de小男生 提交于 2019-11-29 14:47:51
gk5885

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 {}

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);
}

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.

Edit by asker:

I tried the last suggestion.

@Qualifier
@Retention(RUNTIME)
private @interface NoInject {}

@Provides
@Singleton
@NoInject
Foo foo() { return new Foo(); }

Attempting to inject a Foo causes a compile-time error, as desired:

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.

I'd say this sounds a lot like component dependencies.

[..] As an alternative, components can use bindings only from another component interface by declaring a component dependency. When a type is used as a component dependency, each provision method on the dependency is bound as a provider. Note that only the bindings exposed as provision methods are available through component dependencies.

If you really want to hide your Foo and Bar, you could make the module, Foo, and Bar package local. Then create a component that only exposes Qux and use it as a component dependency.

Since Foo and Bar are package local, a SubComponent should not be able to use them, either.
Your component would be the only one able to use the module and thus create and use Foo and Bar in its dependency graph.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!