Я работаю с Active Directory с помощью C#. Инстанцирование 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
:
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
.
Одно из преимуществ этого метода состоит в том, что если объект, которым я владею, изначально не является Disposable, но позже добавляет интерфейс IDisposable
, мой класс будет поступать правильно, даже не меняя его.
Кроме того, использование контейнера DI / IoC может справиться с большей частью этого за вас.
Итак, в основном вы хотите кэшировать дорогой ресурс. Это хорошая вещь.
Глобальные данные (в данном случае статические переменные) - не такая уж хорошая вещь, ИМХО. Вместо этого почему бы не сделать его переменной экземпляра и не контролировать время жизни?
Напишите свой класс, который обрабатывает обязанности AD, попросите его создать и использовать PrincipalContext, а также сделать его IDisposable (используя Dispose Pattern ]). Извлеките из него интерфейс, чтобы отделить его и упростить тестирование классов, которые его используют.
Классы, которые хотят использовать службы AD, будут принимать параметр конструктора вашего нового интерфейса ( Dependency Injection или DI). Вы можете либо создать свой класс вручную в блоке using и передать его классам, либо использовать DI Container Framework . Вы можете настроить фреймворк на время жизни объекта AD равным времени жизни контейнера (который также может быть IDisposable). См. Как согласовать IDisposable и IoC? и документацию по контейнеру DI для получения дополнительной информации.