Dagger 2依赖关系是否不可注入? [英] Can a Dagger 2 dependency be non-injectable?

查看:74
本文介绍了Dagger 2依赖关系是否不可注入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以告诉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 单例,我可以在 Qux 提供程序内创建实例。但是,如果 Qux 具有这样的依赖关系,这将变得很混乱。

  • If the Foo singleton is needed by other providers, I could make it a class member. But this would get messy if Foo has several dependencies of its own.
  • If the Bar singleton is not needed by any other providers, I could create the instance inside the Qux provider. But this would get messy if Qux 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆