Soll ich IDisposable hier implementieren?

7

Meine Methode, die SQL Server aufruft, gibt eine DataReader zurück, aber aufgrund dessen, was ich tun muss - was die DataReader an die aufrufende Methode zurückgibt, die sich in einer Seitenkennung befindet - kann ich die Verbindung nicht schließen in der Klasse der Methode, die SQL Server aufruft. Aus diesem Grund habe ich keine oder blockweise.

Ist die richtige Art Ressourcen zu verteilen, damit die Klasse IDisposable implementiert? Alternativ sollte ich die nicht verwaltete Ressource (Felder auf Klassenebene) vom Aufrufer explizit disponieren?

EDIT: Ich sende den Datenreader zurück, weil ich bestimmte Daten vom Datenreader an ein Listenelement-Steuerelement binden muss, also in der aufrufenden Klasse (Codebehind-Seite) mache ich:

%Vor%     
dotnetdev 19.05.2010, 16:53
quelle

7 Antworten

7

Ich würde ja sagen, implementieren Sie IDisposable . Einer der Hauptgründe, soweit ich es sagen kann, ist, wenn man dem Benutzer des Objekts nicht genug vertrauen kann, um es selbst richtig zu machen. Dies scheint ein Hauptkandidat dafür zu sein.

Dies gesagt, aber es gibt eine Frage zu Ihrer Architektur. Warum möchten Sie das DataReader selbst an die Seite senden, anstatt eine Methode aufzurufen, die es für Sie erledigt (einschließlich der relevanten Bereinigung), indem Sie das Notwendige zurücksenden? Wenn es notwendig ist, der Seite den eigentlichen Leser zu geben, dann sei es so.

    
Kyle Rozendo 19.05.2010, 16:58
quelle
4

Die Datenbankverbindung als Membervariable in Ihrer Reader-Klasse zu halten und Ihre Leserklasse dazu zu bringen, IDisposable zu implementieren, scheint mir in Ordnung zu sein.

Sie können jedoch in Betracht ziehen, dass Ihre Methode IEnumerable zurückgibt und yield return -Anweisungen verwendet, um durch den Datenleser zu gehen. Auf diese Weise können Sie die Ergebnisse zurückgeben und trotzdem von Ihrer Methode bereinigen.

Hier ist eine grobe Skizze dessen, was ich meine:

%Vor%     
Don Kirkby 19.05.2010 17:01
quelle
3

Ja, Sie sollten IDisposable für Ihre benutzerdefinierte Klasse implementieren, wenn sie einen DataReader enthält, der geöffnet ist, wenn er auf eine niedrigere Ebene zurückgegeben wird.

Es ist das akzeptierte Muster, wenn etwas zurückgegeben wird, das aufgeräumt werden muss.

    
driis 19.05.2010 16:59
quelle
3

Erstens ist die Übergabe von DataReader möglicherweise nicht das, was Sie tun möchten, aber ich nehme an, dass es das ist.

Der richtige Weg, um dies zu handhaben, wäre, einen zusammengesetzten Typ zurückzugeben, der entweder DataReader einkapselt oder verfügbar macht und an der Verbindung hält, und dann IDisposable für diesen Typ zu implementieren. Wenn Sie diesen Typ entsorgen, entsorgen Sie sowohl den Reader als auch die Verbindung.

%Vor%     
Adam Robinson 19.05.2010 17:00
quelle
2

Deine Klasse

%Vor%

Dann außerhalb deiner Klasse

%Vor%

Alle Leser und die MyClass -Instanz werden bereinigt, wenn der using -Block beendet wird.

    
Aren 19.05.2010 17:00
quelle
2

Ich würde nichts zurückgeben. Stattdessen würde ich einen Delegierten übergeben.

Zum Beispiel:

%Vor%

Dann in Ihrer Aufrufklasse:

%Vor%     
dss539 19.05.2010 21:18
quelle
1

Die allgemeine Regel lautet, dass Ihre Klasse IDisposable implementieren sollte, wenn sie direkt nicht verwaltete Ressourcen enthält oder einen Verweis auf ein anderes IDisposable -Objekt enthält. Wenn Ihre Klasse in einer Methode IDataReader erstellt, diese Referenz aber nie enthält, müsste Ihre Klasse nicht IDisposable pro Regel implementieren (es sei denn, sie enthält einfach eine IDisposable neben der IDataReader , die in dieser Klasse erstellt wurde eine Methode).

Die wirkliche Frage, die Sie sich stellen müssen, ist, ob Ihre Klasse wirklich an diesem IDataReader festhalten sollte, auch nachdem sie es an den Aufrufer geliefert hat. Persönlich halte ich das für ein schlechtes Design, weil es die Eigentumslinie verwischt. Wem gehört in diesem Fall tatsächlich die IDisposable ? Wer ist für seine Lebenszeit verantwortlich? Nimm zum Beispiel die Klasse IDbCommand . Sie erstellen IDataReader Instanzen und geben sie an die Aufrufer zurück, aber geben sich selbst frei. Das macht die API sauber und die Verantwortung für die Lebensdauerverwaltung ist in diesem Fall eindeutig.

Unabhängig von der Eigentumsfrage erfordert Ihre spezifische Situation die Implementierung von IDisposable; Nicht, weil Ihre Klasse zufälligerweise eine IDataReader -Instanz erstellt und zurückgibt, sondern weil sie sich anhört, als ob sie ein IDbConnection -Objekt enthält.

    
Brian Gideon 19.05.2010 17:33
quelle

Tags und Links