Java 带Dagger的嵌套/递归注入
当使用Dagger时,什么样的方法允许在同样通过注入实例化的对象上自由/轻松地实例化@Inject字段 例如,下面的代码将向给定的Foo对象中注入一个Bar类型的对象。它将以显示的两种方式之一执行此操作。但是,每个条形图对象的Sly字段与该行为不匹配 福 砰 狡猾的 模块 测验Java 带Dagger的嵌套/递归注入,java,android,dagger,Java,Android,Dagger,当使用Dagger时,什么样的方法允许在同样通过注入实例化的对象上自由/轻松地实例化@Inject字段 例如,下面的代码将向给定的Foo对象中注入一个Bar类型的对象。它将以显示的两种方式之一执行此操作。但是,每个条形图对象的Sly字段与该行为不匹配 福 砰 狡猾的 模块 测验 在这两种情况下,Bar的Sly都没有被实例化/@注入。当然,Dagger允许构造函数注入,这就解决了问题。我想知道是否有其他方法可以将这些类塞进构造函数的参数列表中。什么对您有效?所以这里的问题是,Bar上有@Injec
在这两种情况下,Bar的Sly都没有被实例化/@注入。当然,Dagger允许构造函数注入,这就解决了问题。我想知道是否有其他方法可以将这些类塞进构造函数的参数列表中。什么对您有效?所以这里的问题是,Bar上有@InjectSly,但是您在@Provides方法中提供了Bar@提供方法覆盖默认实例化行为,因此您告诉Dagger实例化“new Bar()”,并将其作为Bar规定的实现返回 最简单的方法就是删除provideBar()方法,因为它是不必要的。如果具体类型具有@Inject构造函数或@Inject字段,Dagger将注入其依赖项并创建它,除非它具有不可访问的构造函数或没有@Inject的参数化构造函数。但是您上面的类Bar{}完全适合于隐式绑定,而不使用@Provides方法 如果出于某种原因需要更改默认行为,您仍然可以在@Provides方法中创建它,但必须手动传入注入值@但是,提供方法本身可以通过向@Provides方法本身添加参数来注入。所以你可以这样做
@Provides
Bar provideBar(Sly sly) {
Bar bar = new Bar();
bar.sly = sly;
return bar;
}
@Provides方法承担正确设置实例的所有责任,包括更新、分配、任何初始化逻辑等
但是,根据上面的示例,简单的解决方案是从模块中删除provideBar(),并让Dagger自动初始化Bar
对于嵌套注入,Dagger 2似乎有一些不同的选择:请求一个组件、MembersInjector,或者给Bar一个@Inject注释的构造函数
如果Bar具有@Inject注释的构造函数,则可以实现完全不变性:
class Bar {
private final Sly sly;
@Inject
public Bar(Sly sly) {
this.sly = sly;
}
}
当您仅部分注入成员时,另一种选择是使用@Provides方法和MembersInjector或component(MembersTestComponent?)作为方法参数:
@Provides
Bar provideBar(MembersInjector<Bar> injector) {
Bar bar = new Bar();
injector.inject(bar);
return bar;
}
@提供
棒供应器B(部件喷油器喷油器){
条形=新条形();
注入器。注入器(巴);
返回杆;
}
不幸的是,提供MembersTestComponent参数会将模块耦合回您的组件,从而降低解决方案的内聚性。如果Bar包含组件提供的范围值(例如,Jake Wharton的Devxx 2014演讲中的用户内部Tweeter),则提供MembersInjector特别有用
@Module(
injects = {
Foo.class,
Bar.class
}
)
public class ExampleTestModule {
@Provides
Bar provideBar() {
return new Bar();
}
@Provides
Sly provideSly() {
return new Sly();
}
}
public void testWorksWithInject() {
Foo foo = new Foo();
ObjectGraph.create(new ExampleTestModule()).inject(foo);
assertEquals("...", foo.getValue()); // NullPointerException
}
public void testWorksWithGet() {
Foo foo = ObjectGraph.create(new ExampleTestModule()).get(Foo.class);
assertEquals("...", foo.getValue()); // NullPointerException
}
@Provides
Bar provideBar(Sly sly) {
Bar bar = new Bar();
bar.sly = sly;
return bar;
}
class Bar {
private final Sly sly;
@Inject
public Bar(Sly sly) {
this.sly = sly;
}
}
@Provides
Bar provideBar(MembersInjector<Bar> injector) {
Bar bar = new Bar();
injector.inject(bar);
return bar;
}