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