是否可以在 Dagger 2 中有选择地为组件设置模块?
Is it possible to selectively set modules for components in Dagger 2?
Caused by: java.lang.IllegalStateException: analyticsModule must be set
我正在构建一个使用模板样式初始化的库。用户可以使用该库有选择地为项目设置模块。它使用 Dagger 2 进行 DI。
但是 Dagger 2 似乎不允许可选模块。不能简单地忽略未设置的模块吗?
您可能需要考虑使用多重绑定,它允许用户有选择地将依赖项添加到 Set<T>
或 Map<K,V>
中。这是一个例子:
interface Plugin {
void install(Application application);
}
@Component({ModuleA.class, ModuleB.class})
interface PluginComponent {
Set<Plugin> plugins();
}
@Module
class ModuleA {
@Provides(type = SET) Plugin providFooPlugin() {
return new FooPlugin();
}
}
@Module
class ModuleB {
@Provides(type = SET) Plugin providBarPlugin() {
return new BarPlugin();
}
}
在这种情况下,您仍然需要每个模块的实例,即使它没有被使用。解决此问题的一种选择是使用 @Provides(type = SET_VALUES)
,并将您不想关闭的模块设置为 return Collections.emptySet()
。这是一个修改后的例子:
interface Plugin {
void install(Application application);
}
@Component({ModuleA.class, ModuleB.class})
interface PluginComponent {
Set<Plugin> plugins();
}
@Module
class ModuleA {
private final Set<Plugin> plugins;
ModuleA(Set<Plugin> plugins) {
this.plugins = plugins;
}
@Provides(type = SET_VALUES) Plugin providFooPlugins() {
return plugins;
}
}
@Module
class ModuleB {
@Provides(type = SET) Plugin providBarPlugin() {
return new BarPlugin();
}
}
现在,您可以拨打:
DaggerPluginComponent.builder()
.moduleA(new ModuleA(Collections.emptySet())
.build();
或者:
Set<Plugin> plugins = new HashSet<>();
plugins.add(new AwesomePlugin());
plugins.add(new BoringPlugin());
DaggerPluginComponent.builder()
.moduleA(new ModuleA(plugins)
.build();
Caused by: java.lang.IllegalStateException: analyticsModule must be set
我正在构建一个使用模板样式初始化的库。用户可以使用该库有选择地为项目设置模块。它使用 Dagger 2 进行 DI。
但是 Dagger 2 似乎不允许可选模块。不能简单地忽略未设置的模块吗?
您可能需要考虑使用多重绑定,它允许用户有选择地将依赖项添加到 Set<T>
或 Map<K,V>
中。这是一个例子:
interface Plugin {
void install(Application application);
}
@Component({ModuleA.class, ModuleB.class})
interface PluginComponent {
Set<Plugin> plugins();
}
@Module
class ModuleA {
@Provides(type = SET) Plugin providFooPlugin() {
return new FooPlugin();
}
}
@Module
class ModuleB {
@Provides(type = SET) Plugin providBarPlugin() {
return new BarPlugin();
}
}
在这种情况下,您仍然需要每个模块的实例,即使它没有被使用。解决此问题的一种选择是使用 @Provides(type = SET_VALUES)
,并将您不想关闭的模块设置为 return Collections.emptySet()
。这是一个修改后的例子:
interface Plugin {
void install(Application application);
}
@Component({ModuleA.class, ModuleB.class})
interface PluginComponent {
Set<Plugin> plugins();
}
@Module
class ModuleA {
private final Set<Plugin> plugins;
ModuleA(Set<Plugin> plugins) {
this.plugins = plugins;
}
@Provides(type = SET_VALUES) Plugin providFooPlugins() {
return plugins;
}
}
@Module
class ModuleB {
@Provides(type = SET) Plugin providBarPlugin() {
return new BarPlugin();
}
}
现在,您可以拨打:
DaggerPluginComponent.builder()
.moduleA(new ModuleA(Collections.emptySet())
.build();
或者:
Set<Plugin> plugins = new HashSet<>();
plugins.add(new AwesomePlugin());
plugins.add(new BoringPlugin());
DaggerPluginComponent.builder()
.moduleA(new ModuleA(plugins)
.build();