Dagger2:如何用构造注入实现多@Named注解的Foo单例实例?
Dagger多限定符实例与构造注入的问题解答
嘿,这个问题我之前也琢磨过,刚好能给你理清楚~
首先得明确说:如果你想要同一个Foo类的多个带不同@Named限定符的单例实例,仅靠构造注入是做不到的,你还是需要保留@Provides方法——或者换个思路,但本质上还是需要显式绑定不同的实例。
为什么构造注入搞不定?
Dagger的构造注入逻辑是:一个类的@Inject构造方法只能关联一个限定符(或者没有)。比如你写了:
@Singleton @Named("first") class Foo { @Inject Foo(@Named("first") Bar bar) { /* ... */ } }
这时候Dagger只会用这个构造方法来创建@Named("first")的Foo实例。但对于@Named("second")的Foo,Dagger根本不知道该怎么关联对应的@Named("second")的Bar——因为构造方法的限定符是固定死的,没办法动态切换。
那有没有简化的方式?
虽然不能完全去掉@Provides方法,但你可以把Foo的构造改成@Inject,让@Provides方法更简洁一点:
// 先给Foo加@Inject构造,不用加类级别的@Named和@Singleton class Foo { @Inject Foo(Bar bar) { /* ... */ } } // 然后在模块里的Provider方法简化成这样: @Singleton @Provides @Named("first") static Foo provideFirstFoo(@Named("first") Bar bar) { return new Foo(bar); } @Singleton @Provides @Named("second") static Foo provideSecondFoo(@Named("second") Bar bar) { return new Foo(bar); }
这种写法把构造逻辑移到了Foo类内部,模块里的方法只负责绑定限定符和对应的依赖,比原来的写法更符合单一职责。
总结
如果要保持两个不同@Named的Foo单例,并且每个都对应各自的Bar实例,最直接简洁的方式还是保留@Provides方法。当前Dagger的机制下,同一个类的多限定符实例没办法仅靠构造注入实现。
内容的提问来源于stack exchange,提问作者Piotr Aleksander Chmielowski
相关产品推荐
相关产品推荐

