我正在使用 C# 处理 Active Directory。实例化PrincipalContext
对象似乎很昂贵,所以我想将一个存储在类变量中。
当PrincipalContext
用作局部变量时,我可以使用方便的using
语法。将IDisposable
对象存储在静态变量中时,如何确保正确处理对象?
我正在使用 C# 处理 Active Directory。实例化PrincipalContext
对象似乎很昂贵,所以我想将一个存储在类变量中。
当PrincipalContext
用作局部变量时,我可以使用方便的using
语法。将IDisposable
对象存储在静态变量中时,如何确保正确处理对象?
一般的模式是在你的类上实现IDisposable
接口。举个例子:
public class YourClass : IDisposable
{
private OtherDisposableType yourResource;
public YourClass()
{
yourResource = new OtherDisposableType();
}
public void Dispose()
{
yourResource.Dispose();
}
}
这至少是您需要做的。
编辑
我以前的版本提倡在所有情况下都遵循终结器模式,这被(正确地)指出违反了框架设计指南。但是,如果您实际上正在处理非托管资源(例如,您正在进行直接 P/Invoke 调用并获得需要显式释放的句柄),建议您创建一个终结器并Dispose
在其中调用防止使用您的代码但不调用的人Dispose
:
public class YourClass : IDisposable
{
private OtherDisposableType yourResource;
public YourClass()
{
yourResource = new OtherDisposableType();
}
public void Dispose()
{
yourResource.Dispose();
GC.SuppressFinalize(this);
}
~YourClass()
{
Dispose();
}
}
看看System.ComponentModel
命名空间做了什么。基本上,我通常使用的模式是拥有一组子组件,其中包括我拥有的所有不是“价值”的东西——无论它是否实现IDisposable
.
然后,当我Dispose()
自己时,我会遍历这个集合和Dispose
任何实现IDisposable
.
这种技术的一个优点是,如果我拥有的对象一开始不是一次性的,但后来添加了IDisposable
接口,我的类将做正确的事情而无需更改。
此外,使用 DI/IoC 容器可以为您处理大部分问题。
所以基本上你想缓存一个昂贵的资源。这是好事。
恕我直言,全局数据(在这种情况下为静态变量)并不是一件好事。相反,为什么不让它成为一个实例变量并控制生命周期呢?
编写处理 AD 职责的类,让它创建和使用 PrincipalContext,并将其设置为 IDisposable(使用Dispose 模式)。从中提取一个接口以将其解耦并使使用它的类更易于测试。
想要使用 AD 服务的类将采用新接口的构造函数参数(依赖注入或 DI)。您可以在 using 块中手动创建类并将其传递给类或使用DI Container Framework。您可以让框架将 AD 对象的生命周期设置为容器的生命周期(也可以是 IDisposable)。请参阅如何协调 IDisposable 和 IoC?以及您的 DI 容器文档以了解更多信息。