在模块内部,如果需要基于模块构造时已知的变量提供不同的接口实现,则可以将逻辑放入该接口类型的@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
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
是我能想到的最好,最清晰的替代方法。)
我是使用Dagger2的新手(我一直使用Koin),我正在尝试实现一个简单的示例,但我真的不知道我缺少了什么。这就是我目前得到的。 app.gradle: 应用模块。kt: AppComponent。kt: TestClass。千吨 pp.kt: MainActivity.kt: 错误:testClass==null
我的项目有多个具有方法的类。如何告诉Spring Boot Maven插件应该使用哪个类作为主类?
本文向大家介绍基于spring如何实现事件驱动实例代码,包括了基于spring如何实现事件驱动实例代码的使用技巧和注意事项,需要的朋友参考一下 干货点 通过阅读该篇博客,你可以了解了解java的反射机制、可以了解如何基于spring生命周期使用自定义注解解决日常研发问题。具体源码可以点击链接。 问题描述 在日常研发中,经常会遇见业务A的某个action被触发后,同时触发业务B的action的行为,
我使用Spock进行测试,我有多个类要测试。我想告诉Spock按照特定的顺序测试每个类。有办法做到这一点吗?我注意到TestNG有注释,那么Spock也有类似的注释吗?
我使用和将日期字符串从1970年起传递到毫秒。 问题是日期字符串上不包含时区。他们是英国人,所以时区将是GMT或GMT+1取决于日期... 当我在前端(Chrome)或后端(Node.js)中使用此技术时。所取时区为英国时区(GMT或GMT+1,视日期而定)。我认为这是从操作系统中提取的。 但是,在使用Node.js服务器时,我被告知该服务器配置为UTC格式...时区总是格林尼治标准时间,导致英国
我正在为Eclipse Juno编写一个插件,我想使用类AbstractSourceLookupDirector。当我查看API时,它说它有一个构造函数,但是当我在代码中使用以下语句时,它说“不能实例化类型AbstractSourceLookupDirector” AbstractSourceLookupDirector srclookupDir=新的AbstractSourceLookupDir