Dagger2 将相同基类型的 Provider 聚合到 Array 或 Collection 中?
Dagger2 aggregate Providers of same base type into Array or Collection?
我有很多接口 Foo
的对象。所以我有很多 Foo
的供应商,没问题。
我的问题是我有一个对象需要一组 foo(所有 Foo)。考虑以下因素:
@Module
@AppScope
public class AppModule {
//OTHER PROVIDERS MY FOO'S DEPEND ON OMITTED
@Provides
AaFoo provideAaFoo(){
return new AaFoo();
}
@Provides
BbFoo provideBbFoo(){
return new BbFoo();
}
@Provides
CcFoo providesCcFoo(Something something) {
return new CcFoo(something);
}
//EVEN MORE KINDS OF FOO's...
//Now I need to provide a thing that holds all Foo's
//TODO: This pattern is horribly ugly!
@Provides
FooManager provideFooManager(
AaFoo aa,
BbFoo bb,
CcFoo cc,
...) {//each time I make a foo I have to add; mention it here
FooManager fooService = new FooManager();
fooService.addFoo(aa);
fooService.addFoo(bb);
fooService.addFoo(cc);
fooService.addFoo(dd);
... //and I need to put it here, how nice it would be if this were a collection...
return fooService;
}
}
有没有办法让 dagger 将所有 foo 聚合到一个集合中,这样我就可以将该集合传递给我的 provideRouteService
方法?这样当我添加更多 foo 时一切正常吗?
啊,答案在 Multibindings(https://google.github.io/dagger//multibindings.html) 中,而且非常简单:
将上面的简单转换为:
- 将@IntoSet 添加到我的每个 Foo 提供程序。
- 全部使用 return Foo 而不是子类型
- 让 FooProvider 获取一个集合
示例:
@Module
@AppScope
public class AppModule {
//OTHER PROVIDERS MY FOO'S DEPEND ON OMITTED
@Provides
@IntoSet
Foo provideAaFoo(){
return new AaFoo();
}
@Provides
@IntoSet
Foo provideBbFoo(){
return new BbFoo();
}
@Provides
@IntoSet
Foo providesCcFoo(Something something) {
return new CcFoo(something);
}
//EVEN MORE KINDS OF FOO's...
//Now I need to provide a thing that holds all Foo's
//TODO: This pattern isn't ugly any more!
@Provides
FooManager provideFooManager(
Set<Foo> foos) {
return new FooManager(foos);
}
}
还用@Inject 注释了FooManager 的构造函数。清晰多了!
我有很多接口 Foo
的对象。所以我有很多 Foo
的供应商,没问题。
我的问题是我有一个对象需要一组 foo(所有 Foo)。考虑以下因素:
@Module
@AppScope
public class AppModule {
//OTHER PROVIDERS MY FOO'S DEPEND ON OMITTED
@Provides
AaFoo provideAaFoo(){
return new AaFoo();
}
@Provides
BbFoo provideBbFoo(){
return new BbFoo();
}
@Provides
CcFoo providesCcFoo(Something something) {
return new CcFoo(something);
}
//EVEN MORE KINDS OF FOO's...
//Now I need to provide a thing that holds all Foo's
//TODO: This pattern is horribly ugly!
@Provides
FooManager provideFooManager(
AaFoo aa,
BbFoo bb,
CcFoo cc,
...) {//each time I make a foo I have to add; mention it here
FooManager fooService = new FooManager();
fooService.addFoo(aa);
fooService.addFoo(bb);
fooService.addFoo(cc);
fooService.addFoo(dd);
... //and I need to put it here, how nice it would be if this were a collection...
return fooService;
}
}
有没有办法让 dagger 将所有 foo 聚合到一个集合中,这样我就可以将该集合传递给我的 provideRouteService
方法?这样当我添加更多 foo 时一切正常吗?
啊,答案在 Multibindings(https://google.github.io/dagger//multibindings.html) 中,而且非常简单:
将上面的简单转换为:
- 将@IntoSet 添加到我的每个 Foo 提供程序。
- 全部使用 return Foo 而不是子类型
- 让 FooProvider 获取一个集合
示例:
@Module
@AppScope
public class AppModule {
//OTHER PROVIDERS MY FOO'S DEPEND ON OMITTED
@Provides
@IntoSet
Foo provideAaFoo(){
return new AaFoo();
}
@Provides
@IntoSet
Foo provideBbFoo(){
return new BbFoo();
}
@Provides
@IntoSet
Foo providesCcFoo(Something something) {
return new CcFoo(something);
}
//EVEN MORE KINDS OF FOO's...
//Now I need to provide a thing that holds all Foo's
//TODO: This pattern isn't ugly any more!
@Provides
FooManager provideFooManager(
Set<Foo> foos) {
return new FooManager(foos);
}
}
还用@Inject 注释了FooManager 的构造函数。清晰多了!