6

我正在使用 C# 处理 Active Directory。实例化PrincipalContext对象似乎很昂贵,所以我想将一个存储在类变量中。

PrincipalContext用作局部变量时,我可以使用方便的using语法。将IDisposable对象存储在静态变量中时,如何确保正确处理对象?

4

3 回答 3

7

一般的模式是在你的类上实现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();
    }
}
于 2010-03-14T00:51:07.970 回答
2

看看System.ComponentModel命名空间做了什么。基本上,我通常使用的模式是拥有一组子组件,其中包括我拥有的所有不是“价值”的东西——无论它是否实现IDisposable.

然后,当我Dispose()自己时,我会遍历这个集合和Dispose任何实现IDisposable.

这种技术的一个优点是,如果我拥有的对象一开始不是一次性的,但后来添加了IDisposable接口,我的类将做正确的事情而无需更改。

此外,使用 DI/IoC 容器可以为您处理大部分问题。

于 2010-03-14T00:58:45.473 回答
1

所以基本上你想缓存一个昂贵的资源。这是好事。

恕我直言,全局数据(在这种情况下为静态变量)并不是一件好事。相反,为什么不让它成为一个实例变量并控制生命周期呢?

编写处理 AD 职责的类,让它创建和使用 PrincipalContext,并将其设置为 IDisposable(使用Dispose 模式)。从中提取一个接口以将其解耦并使使用它的类更易于测试。

想要使用 AD 服务的类将采用新接口的构造函数参数(依赖注入或 DI)。您可以在 using 块中手动创建类并将其传递给类或使用DI Container Framework。您可以让框架将 AD 对象的生命周期设置为容器的生命周期(也可以是 IDisposable)。请参阅如何协调 IDisposable 和 IoC?以及您的 DI 容器文档以了解更多信息。

于 2010-03-14T00:58:06.053 回答