Wie mache ich ein idisposables Objekt zu einer Klassenvariable?
-
19-09-2019 - |
Frage
Ich arbeite mit Active Directory mit C#. Instanzipieren des PrincipalContext
Objekt scheint teuer zu sein, also möchte ich eine in einer Klassenvariablen speichern.
Beim Benutzen PrincipalContext
Als lokale Variable kann ich den bequemen verwenden using
Syntax. Beim Speichern von IDisposable
Objekt in einer statischen Variablen, wie stelle ich sicher, dass das Objekt ordnungsgemäß entsorgt wird?
Lösung
Das allgemeine Muster dafür ist die Implementierung der IDisposable
Schnittstelle in Ihrer Klasse. Nehmen Sie dieses Beispiel:
public class YourClass : IDisposable
{
private OtherDisposableType yourResource;
public YourClass()
{
yourResource = new OtherDisposableType();
}
public void Dispose()
{
yourResource.Dispose();
}
}
Dies ist mindestens das, was Sie tun müssen.
BEARBEITEN
Meine frühere Version befürwortete in allen Fällen nach dem Finalizer -Muster, was (korrekt) gegen die Richtlinien für das Rahmendesign festgestellt wurde. Für den Fall, dass Sie sich jedoch mit nicht verwalteten Ressourcen befassen (z. B. direkte P/Invoke -Anrufe und ein Handle, das ausdrücklich befreit werden muss), ist es ratsam, einen Finalizer und Anrufe zu erstellen und anzurufen Dispose
darin, um vor Menschen zu schützen, die Ihren Code konsumieren und nicht anrufen Dispose
:
public class YourClass : IDisposable
{
private OtherDisposableType yourResource;
public YourClass()
{
yourResource = new OtherDisposableType();
}
public void Dispose()
{
yourResource.Dispose();
GC.SuppressFinalize(this);
}
~YourClass()
{
Dispose();
}
}
Andere Tipps
Schau dir an, was die System.ComponentModel
Namespace tut. Grundsätzlich besteht das Muster, das ich normalerweise verwende IDisposable
.
Dann, wenn ich Dispose()
Ich selbst, ich itere über diese Sammlung und Dispose
Alles, was impliziert IDisposable
.
Ein Vorteil dieser Technik ist, dass, wenn ein Objekt, das ich besitze, nicht verfügbar ist, aber später das hinzufügt IDisposable
Schnittstelle, meine Klasse wird das Richtige tun, ohne sich jemals ändern zu müssen.
Außerdem kann die Verwendung eines DI/IOC -Behälters viel davon für Sie verarbeiten.
Im Grunde möchten Sie also eine teure Ressource zwischenspeichern. Das ist gut.
Globale Daten (statische Variablen in diesem Fall) sind nicht so gut, IMHO. Machen Sie es stattdessen nicht zu einer Instanzvariablen und steuern Sie die Lebensdauer?
Schreiben Sie Ihre Klasse, die die Anzeigenverantwortung übernimmt, den PrincipalContext erstellen und verwenden und es auch identifizieren lassen Muster entsorgen). Extrahieren Sie eine Schnittstelle davon, um sie zu entkoppeln und Klassen zu ermöglichen, die sie leichter testen.
Klassen, die AD -Dienste verwenden möchten, nehmen einen Konstruktorparameter Ihrer neuen Schnittstelle an (Abhängigkeitsspritze oder di). Sie können Ihre Klasse entweder manuell in einem benutzten Block erstellen und an die Klassen weitergeben oder a verwenden DI -Container -Framework. Sie können das Framework die Lebensdauer des AD -Objekts auf die Lebensdauer des Containers festlegen (was auch identifizierbar ist). Sehen Wie können Sie idisposable und IOC in Einklang bringen? und Ihre DI -Container -Dokumentation dazu.