- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我想执行一系列处理元素并通过 Guice 将它们连接在一起。让我们假设以下路径:
interface A
由 class AImpl
实现需要一些输入interface B
由 class BImpl
实现需要 A
接口(interface)C
由类CImpl
实现需要B
接口(interface)D
由类DImpl
实现需要C
A 的依赖只能在运行时解决,不能在配置时解决。通常的方法是在这种情况下使用辅助注入(inject)来创建一个工厂,它将丢失的实例作为参数,就像这样:
public interface AFactory {
public A createA(String input);
}
但我真正想要的是这样的:
public interface DFactory {
public D createD(String inputForA);
}
我不想在整个层次结构中手动传递特定于 AImpl
的依赖项。有可能用 Guice 实现吗?如果不是,那么在保留注入(inject)优势的同时优雅地规避这个问题的最佳方法是什么?
最佳答案
作弊方式:贴input
在静态变量或单例中 ThreadLocal
.在您的管道开始之前设置它并在它结束后清除它。通过 DI 绑定(bind)其他所有内容。
奇特的方式:在A
, 引用 @PipelineInput String inputString
但不要将其绑定(bind)在主喷油器中。否则,像往常一样绑定(bind)依赖项,包括引用 @PipelineInput
在其他与管道相关的类中。当您确实需要 D
时, 从您的 DFactory
实现中获取它,我称之为 PipelineRunner
.
public class PipelineRunner {
@Inject Injector injector; // rarely a good idea, but necessary here
public D createD(final String inputForA) {
Module module = new AbstractModule() {
@Override public void configure() {
bindConstant(inputForA).annotatedWith(PipelineInput.class);
}
};
return injector.createChildInjector(new PipelineModule(), module)
.getInstance(D.class);
}
}
自然地,对 A
的绑定(bind)尝试, B
, C
, 和 D
将在 PipelineRunner
之外失败因为缺少 @PipelineInput String
--你会得到一个CreationException
正如您发现的那样,当您使用那些未满足的依赖项创建注入(inject)器时——但是这些基于管道的依赖项应该很容易分离到一个模块中,然后安装到子注入(inject)器中。
如果这感觉太 hacky,请记住 PrivateModules 也是“implemented using parent injectors”,并且依赖注入(inject)的全部要点是建立一个像 inputForA
这样的依赖。以解耦的方式提供给整个对象图。
关于java - Guice 辅助注入(inject)更深的依赖层次结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16316719/
我是一名优秀的程序员,十分优秀!