C# 如何确保不处置其他人仍在使用的对象
我有一个使用构造函数注入的类C# 如何确保不处置其他人仍在使用的对象,c#,.net,dependency-injection,dispose,C#,.net,Dependency Injection,Dispose,我有一个使用构造函数注入的类 public class MyClass { public MyClass(IInterface1 interface1) { } public Dispose() { interface1.dispose(); } } 接口1将由DI注入。但有时,我需要手动创建MyClass public class MyOtherClass {
public class MyClass
{
public MyClass(IInterface1 interface1)
{
}
public Dispose()
{
interface1.dispose();
}
}
接口1将由DI注入。但有时,我需要手动创建MyClass
public class MyOtherClass
{
private readonly IInterface1 _interface1;
public MyOtherClass()
{
_interface1 = new Interface1();
}
public Foo()
{
foo = new MyClass(_interface1);
bar = new MyClass(_interface1);
}
}
在我的dispose方法中,当MyClass被销毁时,interface1总是被释放。问题是,interface1由MyOtherClass拥有,并且可能仍被其他实例使用,因此不应予以处置。我如何解决这个问题?你不应该打电话
interface1.dispose();
在我的班级里
如果interface1是由DI容器创建的,那么它将在那里重新创建。
如果您在MyOtherClass中显式创建它,请在MyOtherClass中处理它。您不应该调用
interface1.dispose();
在我的班级里
如果interface1是由DI容器创建的,那么它将在那里重新创建。
如果要像在MyOtherClass中那样显式创建它,请在MyOtherClass中处理它。您的代码有两个问题 首先,
MyClass
“非法”取得了IInterface1
的所有权,但它不知道该实例的生存期是什么。这意味着如果重复使用IInterface1
,系统将中断
所有权的基本规则是“创建实例的人负责处理它”(The)。因为MyClass
没有创建IInterface1
,所以他不应该处理它<因此,code>MyClass不应实现Dispose
方法,也不应调用IInterface1.Dispose()
其次,通过让IInterface1
实现IDisposable
,您的代码违反了(DIP),因为DIP声明:
抽象不应该依赖于细节。细节应视情况而定
抽象概念
但是,您的IInterface1
取决于实现细节,因为某个组件是否具有需要处置的非托管资源是一个实现细节。该IInterface1
的每个实现都不太可能总是需要处理资源,因此您的接口泄漏了特定实现的实现细节
因此,与其让IInterface1
实现IDisposable
,不如让给定的实现实现IDisposable
。这样做的好处在于它最小化了IInterface1
的API,这使得它更易于使用,并且可能允许您遵守API
如果您这样做,问题会立即消失,因为MyClass
不知道IInterface1
是否可以被释放(这很好),这意味着它首先不能意外调用Dispose
当然,这就让创建该实例的系统部分来处理该实例(这很好)。如果此实例是由DI库(如果您使用DI库)代表您创建的,则DI库通常负责处理该实例。如果您不使用容器,您必须确保自己进行处理
请注意,并非所有容器都跟踪所有实例。例如,Unity和Simple Injector不会自动跟踪(和处理)瞬态实例。然而,在大多数情况下,一次性组件应该以限定的生活方式注册(按照web请求或类似的方式)。我认为在这种情况下,所有容器都会处理以这种方式注册的实例。您的代码有两个问题 首先,
MyClass
“非法”取得了IInterface1
的所有权,但它不知道该实例的生存期是什么。这意味着如果重复使用IInterface1
,系统将中断
所有权的基本规则是“创建实例的人负责处理它”(The)。因为MyClass
没有创建IInterface1
,所以他不应该处理它<因此,code>MyClass不应实现Dispose
方法,也不应调用IInterface1.Dispose()
其次,通过让IInterface1
实现IDisposable
,您的代码违反了(DIP),因为DIP声明:
抽象不应该依赖于细节。细节应视情况而定
抽象概念
但是,您的IInterface1
取决于实现细节,因为某个组件是否具有需要处置的非托管资源是一个实现细节。该IInterface1
的每个实现都不太可能总是需要处理资源,因此您的接口泄漏了特定实现的实现细节
因此,与其让IInterface1
实现IDisposable
,不如让给定的实现实现IDisposable
。这样做的好处在于它最小化了IInterface1
的API,这使得它更易于使用,并且可能允许您遵守API
如果您这样做,问题会立即消失,因为MyClass
不知道IInterface1
是否可以被释放(这很好),这意味着它首先不能意外调用Dispose
当然,这就让创建该实例的系统部分来处理该实例(这很好)。如果此实例是由DI库(如果您使用DI库)代表您创建的,则DI库通常负责处理该实例。如果您不使用容器,您必须确保自己进行处理
请注意,并非所有容器都跟踪所有实例。例如,Unity和Simple Injector不会自动跟踪(和处理)瞬态实例。然而,在大多数情况下,一次性组件应该以限定的生活方式注册(按照web请求或类似的方式)。我想在那种情况下,一切都包括在内