在模块内部,如果我需要基于模块构造时已知的变量提供接口的不同实现,则可以将逻辑放入该接口类型的@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创建。我宁愿说“嘿,基于XI希望您为我实例化此类”
我考虑了几种选择。
更改提供方法以采用所有可能的实现:
@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方法以获取不同实现的所有依赖项的集合。
@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()。我会尽量尝试并发布结果
而不是使用Lazy<T>
选项1 Provider<T>
。Lazy<T>
只是一个Provider<T>
在本地存储的(具有必要的双重检查锁定),但是因为您知道只将一个提供者调用一次,所以您可以注入该提供者,而跳过同步开销。
@Provides
FooInterface provideFooImplementation(
Provider<FooImpl1> impl1,
Provider<FooImpl2> impl2,
...,
Provider<FooImpl10> impl10) {
switch(state) {
case STATE_1:
return impl1.get();
case STATE_2:
return impl2.get();
...
case STATE_10:
return impl10.get();
}
}
选项2可以使用,但是您将有效地跳过Dagger可以轻松为您完成的依赖关系接线,并且选项3不能按所述方式工作,因为@Component注释需要模块列表作为您的编译时常量Dagger代码生成可以正常工作。
(如果将绑定绑定到一种形式或另一种形式的常数或零依赖类,则选项3的变体可以工作,因为这样您可以将Module的任意子类传递到Component Builder中。但是,Dagger只能分析如果您的@Provides方法实现采用的参数与您使用的参数不同,那么您将遇到麻烦,因此,这switch
是我能想到的最好,最清晰的替代方法。)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句