【发布时间】:2019-09-09 19:45:34
【问题描述】:
在我的项目中,我到处使用依赖注入,并在两种情况下使用临时工厂。首先,当我想准确控制创建实例的时间时,我会注入工厂而不是实例:
// WidgetA must be created before WidgetB, because of the side-effects
// on the container.
WidgetAFactory.make(container);
WidgetBFactory.make(container);
另一种情况是构造函数采用可注入值和运行时值的混合。而不是使用:
@Inject
WidgetC(
Container,
@WidgetCFont Font,
@WidgetCColor Color,
@Named("flag") String flag) {
...
}
我用:
@Inject
WidgetCFactory(
@WidgetCFont Font font,
@WidgetCColor Color color,
@Named("flag") String flag) {
...
}
WidgetCFactory.make(Container container) {
return new WidgetC(container, font, color, flag);
}
但是我在使用工厂时遇到了两个限制:
在我的第一个示例中,我还需要 WidgetA 成为其他 @Injected 构造函数所需的 @Singleton。到目前为止,我的解决方案是将调用工厂时创建的实例存储起来,并@Provides 供其他人使用。有没有办法将这个单例的控制权交还给 guice,而不必自己维护那个实例?
在我的第二个示例中,管理注入的依赖项是一团糟:WidgetCFactory 必须使用一长串注入值调用 WidgetC 构造函数,必须针对依赖项中的每次更改进行更新,没有注释检查。有没有办法为 Guice 提供运行时参数,并让它处理其他依赖项?
感觉对于这两种情况,我都可以使用一个子注入器,它会被赋予运行时值,并让 Guice 成为工厂:
public static class WidgetCFactory {
private final Injector injector;
@Inject
public WidgetCFactory(Injector injector) {
this.injector = injector;
}
public WidgetC make(Container container) {
Injector childInjector = injector.createChildInjector(new AbstractModule() {
@Override protected void configure() {
bind(Container.class).toInstance(container);
}
});
return childInjector.getInstance(WidgetC.class);
}
}
但我没有发现很多人这样做。是因为它太重了,还是超出了依赖注入的良好实践?有什么更好的方法?
【问题讨论】:
标签: dependency-injection guice factory