我对依赖注入有一个普遍的理解问题,独立于特定的依赖注入框架。假设我有一个需要运行时参数的类:
class ClassWithRuntimeDependency {
ClassWithRuntimeDependency (String myRuntimeParameter) {
//...
}
}
现在要将这个运行时参数放到我的类中,几个依赖注入框架的文档告诉我使用工厂。此工厂获取运行时参数并使用它创建ClassWithRunetimeDependency
的实例。
但是,让我们说这个ClassWithRuntimeDependency
是一个非常基本的类,几乎所有其他类都需要它:
Class A -> Class B -> Class C -> Factory<ClassWithRuntimeDependency>
。
现在我无法创建没有此运行时依赖项的C类,因此我需要为它创建一个工厂。但同样适用于A类和B类!这导致A类的工厂具有运行时依赖性,仅在构造ClassWithRuntimeDependency
时需要。这意味着我不会将直接依赖注入A类,这也不是最佳实践(github)。我知道我也可以将这个运行时依赖项引入所有需要的方法,而不是在任何地方使用工厂,但这只会改变问题。
我在这里有误解或有更好的解决方法吗?
为了进一步表达问题,如果我到处使用工厂,这可能是我的A-C类:
// Needs a factory because of runtime parameter.
// Imho, this is the only class which should really need a factory because
// it is the only class having the direct runtime dependency, all
// others below are indirect
class ClassWithRuntimeDependency {
ClassWithRuntimeDependency (String myRuntimeParameter) {
//...
}
}
// Needs a factory because of runtime parameter in ClassWithRuntimeDependendcy
class C {
C(String myRuntimeParameter, @inject FactoryForClassWithRuntimeDependency reallyNeededFactory) {
this.withRuntimeDependency = reallyNeededFactory(myRuntimeParameter);
}
}
// Needs a factory because of runtime parameter in C -> ClassWithRuntimeDependendcy
class B {
B(String myRuntimeParameter, @inject FactoryForC cFactory) {
this.c = cFactory(myRuntimeParameter);
}
}
// Needs a factory because of runtime parameter in B -> C -> ClassWithRuntimeDependendcy
class A {
A(String myRuntimeParameter, @inject FactoryForB bFactory) {
this.b = bFactory(myRuntimeParameter);
}
}
(我没有使用特定DI框架的语法)
所以我最终得到一个只有AFactory
需要的ClassWithRuntimeDependency
依赖项。当然,我也可以在构造函数中省略参数并仅使用它的方法(as suggested here),但如果我在这些类中的任何一个方法中都有许多需要此参数的方法,那么这真的会让我的API全部爆炸依赖类,因此只会改变问题。
我到目前为止唯一的解决方案是注入context
对象(或context
对象的提供者),并使用运行时数据填充此上下文对象。但这也会导致temporal coupling并使测试变得更难。
答案 0 :(得分:-2)
这就是为什么你应该有控制反转容器并允许他为你做脏事。像 Spring 那样。您只需通过配置指出bean所需的依赖关系, Spring 注入此依赖关系。