dependency injection – 几个类方法中需要的新实例
我有一些看起来像这样的代码:
public MyService(IDependency dependency) { _dependency = dependency; } public Message Method1() { _dependency.DoSomething(); } public Message Method2() { _dependency.DoSomething(); } public Message Method2() { _dependency.DoSomething(); }
现在我刚刚意识到,因为依赖对象包含内部状态信息。 我需要在每个方法调用中新建一个新实例
那么,最好的方法是什么,仍然没有新的具体实例?
您是否会使用IoC容器并在每个方法中调用容器? 或者是否有一种更流畅的方式,您只能拨打一个容器?
如果我没有使用IoC容器怎么办?是否有办法不在每个方法中新建一个具体的实例?
到目前为止,大多数答案都建议您将注入的依赖类型更改为某种抽象工厂 ( Func
也是一个抽象工厂)来解决该问题。 但是,如果你这样做,那将是一个漏洞抽象,因为你会让特定实现的知识决定消费者的设计 。 这违反了Liskov替代原则 。
更好的选择是保持MyService不变 ,然后为IDependency创建一个解决特定生命周期问题的包装器:
public class TransientDependencyWrapper : IDependency { public void DoSomething() { new MyStatefulDependency().DoSomething(); } }
将其注入MyService而不是直接注入原始实现(MyStatefulDependency)。
如果要抽象出依赖项的创建,可以始终在此级别注入抽象工厂。
听起来你应该注射供应商/工厂。 你如何表示这取决于你(以及你的IoC支持) – 它可以简单到:
public MyService(Func dependencyProvider) { this.dependencyProvider = dependencyProvider; } public Message Method1() { IDependency dependency = dependencyProvider(); dependency.DoSomething(); }
…或者您可以拥有这种特定工厂类型的接口,或者通用的IFactory
等。有各种可能性 – 但核心位是您注入所需的东西,在这种情况下是“a在每次调用时创建IDependency
的新实现的IDependency
“。
如果需要创建多个注入类型的实例,则应该注入一个IDependencyFactory
,它将负责控制实例生命周期:
interface IDependencyFactory { IDependency GetInstance(); }
你可以这样做:
private readonly Func _dependancy; public MyService(Func dependancy) { _dependancy = dependancy; } public Message Method1() { _dependancy().DoSomething(); } public Message Method2() { _dependancy().DoSomething(); } public Message Method3() { _dependancy().DoSomething(); }
然后:
var service = new MyService(() => new SomeConcreteDependency()); service.Method1(); service.Method2(); service.Method3();
我头脑中的前两个想法是
- 不要在构造函数中使用它,而是在每个方法上接受它。
- 不是将实例传递给构造函数,而是传入工厂或
Func
,每次调用func时都会创建一个新实例。