Как заставить IDisposable возразить переменной класса?

Я работаю с Active Directory с помощью C#. Инстанцирование PrincipalContext объект, кажется, является дорогим, таким образом, я хотел бы сохранить один в переменной класса.

При использовании PrincipalContext как локальная переменная, я могу использовать удобное using синтаксис. При хранении IDisposable от объекта в статической переменной, как я гарантирую объект, правильно избавляются?

6
задан Ben 14 March 2010 в 00:44
поделиться

3 ответа

Общий шаблон для этого - реализация IDisposable ] интерфейс вашего класса. Возьмем следующий пример:

public class YourClass : IDisposable
{
    private OtherDisposableType yourResource;

    public YourClass()
    {
        yourResource = new OtherDisposableType();
    }

    public void Dispose()
    {
        yourResource.Dispose();
    }
}

Это, как минимум, то, что вам нужно сделать.

РЕДАКТИРОВАТЬ

В моей предыдущей версии во всех случаях предлагалось следовать шаблону финализатора, что (правильно) противоречило руководящим принципам разработки фреймворка. Однако в случае, если вы действительно имеете дело с неуправляемыми ресурсами (например, выполняете прямые вызовы P / Invoke и получаете дескриптор, который необходимо явно освободить), рекомендуется создать финализатор и вызвать Разместите в нем , чтобы защитить себя от людей, которые используют ваш код и не вызывают Dispose :

public class YourClass : IDisposable
{
    private OtherDisposableType yourResource;

    public YourClass()
    {
        yourResource = new OtherDisposableType();
    }

    public void Dispose()
    {
        yourResource.Dispose();

        GC.SuppressFinalize(this);
    }

    ~YourClass()
    {
        Dispose();
    }
}
7
ответ дан 10 December 2019 в 00:36
поделиться

Посмотрите, что делает пространство имен System.ComponentModel . По сути, шаблон, который я обычно использую, состоит в том, чтобы иметь набор подкомпонентов, который включает все, что у меня есть, кроме «значения» - независимо от того, реализует ли он IDisposable .

Затем, когда я сам Dispose () , я перебираю эту коллекцию и Dispose все, что реализует IDisposable .

Одно из преимуществ этого метода состоит в том, что если объект, которым я владею, изначально не является Disposable, но позже добавляет интерфейс IDisposable , мой класс будет поступать правильно, даже не меняя его.

Кроме того, использование контейнера DI / IoC может справиться с большей частью этого за вас.

2
ответ дан 10 December 2019 в 00:36
поделиться

Итак, в основном вы хотите кэшировать дорогой ресурс. Это хорошая вещь.

Глобальные данные (в данном случае статические переменные) - не такая уж хорошая вещь, ИМХО. Вместо этого почему бы не сделать его переменной экземпляра и не контролировать время жизни?

Напишите свой класс, который обрабатывает обязанности AD, попросите его создать и использовать PrincipalContext, а также сделать его IDisposable (используя Dispose Pattern ]). Извлеките из него интерфейс, чтобы отделить его и упростить тестирование классов, которые его используют.

Классы, которые хотят использовать службы AD, будут принимать параметр конструктора вашего нового интерфейса ( Dependency Injection или DI). Вы можете либо создать свой класс вручную в блоке using и передать его классам, либо использовать DI Container Framework . Вы можете настроить фреймворк на время жизни объекта AD равным времени жизни контейнера (который также может быть IDisposable). См. Как согласовать IDisposable и IoC? и документацию по контейнеру DI для получения дополнительной информации.

1
ответ дан 10 December 2019 в 00:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: