在模块内部,如果我需要基于模块构造时已知的变量提供接口的不同实现,我可以将逻辑放入该接口类型的 @Provides 方法中。就像这样:
@Module
public class FooModule {
private final State state;
public FooModule(State state) {
this.state = state;
}
@Provides
FooInterface provideFooImplementation() {
switch(state) {
case STATE_1:
return new FooImpl1();
case STATE_2:
return new FooImpl2();
...
case STATE_10:
return new FooImpl10();
}
}
}
然而,这些实现可以由 Dagger 创建。我宁愿说“嘿,基于X我希望你为我实例化这个类”
我考虑过几个选择。
-
更改提供方法以接受所有可能的实现:
@Provides
FooInterface provideFooImplementation(FooImpl1 impl1, FooImpl2 imp2, ..., FooImpl10 impl10) {
switch(state) {
case STATE_1:
return impl1;
case STATE_2:
return impl2;
...
case STATE_10:
return impl10;
}
}
这允许 Dagger 实例化它们并满足它们的所有依赖关系,但如果每个实现都相对较大或创建成本较高,那么这不是一个好主意。
-
更改提供方法以获取不同实现的所有依赖项的集合。
@Provides
FooInterface provideFooImplementation(Context context, Repo repo, HttpClient httpClient, ...) {
switch(state) {
case STATE_1:
return new FooImpl1(context);
case STATE_2:
return new FooImpl2(repo, httpClient);
...
case STATE_10:
return new FooImpl10(context, repo);
}
}
这比选项 1 稍好一些,因为 Dagger 不必实例化每个实现,但它仍然需要实例化所有依赖项,即使它们可能不会在所有情况下使用。我也重新开始自己创建对象,尽管它们可以由 Dagger 创建。
-
为每个实现创建一个模块并实例化适当的模块。所以像这样:
@Module
public FooImpl1Module {
@Provides
FooInterface provideFooImplementation(Context context) {
return new FooImpl1(context);
}
}
这很好,但现在我在定义依赖于模块的组件时遇到了问题。
解决这个问题的最佳方法是什么?
一项建议是尝试使用 Lazy 封装的参数的选项 1。然后我最终只在其中一个上调用 .get() 。我会尽可能尝试并发布结果
一个可能的解决方案是使用@Named("foo")
注释与支持组件提供方法而不是手动注入相结合,但这意味着您的状态将独立于模块本身,并且您将是做出选择的人
@Component(modules={FooModule.class})
public interface AppComponent {
@Named("STATE_1")
FooInterface fooImpl1();
@Named("STATE_2")
FooInterface fooImpl2();
...
@Named("STATE_10")
FooInterface fooImpl10();
}
@Module
public FooImpl1Module {
@Provides
@Named("STATE_1")
FooInterface provideFooImpl1(Context context) {
return new FooImpl1(context);
}
@Provides
@Named("STATE_2")
FooInterface provideFooImpl2(Context context) {
return new FooImpl2(context);
}
...
@Provides
@Named("STATE_10")
FooInterface provideFooImpl10(Context context) {
return new FooImpl10(context);
}
}
然后你可以打电话
FooInterface fooInterface = component.fooImpl1();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)