Frage

Ich habe ein Objekt, das IDisposable implementiert, die mit dem Windsor Container registriert ist, und ich möchte es entsorgen, so ist es Dispose-Methode aufgerufen wird, und das nächste Mal Resolve aufgerufen wird es holt eine neue Instanz.

Does

container.Release(obj); 

automatisch aufrufen Dispose () sofort? Oder muss ich tun

obj.Dispose();
container.Release(obj);

kann nicht alles in der Dokumentation auf, was genau entbindet

EDIT: Siehe meine Antwort unten für die Ergebnisse der Tests, die ich lief. Jetzt die Frage, wie erzwinge ich den Container eine Instanz einer Komponente mit einem Singleton-Lebenszyklus zu veröffentlichen? Dies muss nur an einem Ort und das Schreiben eines benutzerdefinierten Lebenszyklus getan werden viel zu Schwergewicht scheint, gibt es keine integrierte Art und Weise, es zu tun?

War es hilfreich?

Lösung

Das ist etwas, was ich Leute denken, sind nicht wirklich bewusst, wenn sie mit dem Windsor Container arbeiten - vor allem die oft überraschend Verhalten, dass das verfügbare transienten Komponenten auf durch die gehalten werden Behälter für die gesamte Lebensdauer des Kernels, bis sie, wenn Sie sie selbst entsorgt Freilassung - obwohl dokumentiert wird - schauen Sie hier - aber schnell Zitat:

  

Der Mikrokernel hat eine steckbare Release-Politik, die einige Haken und implementieren   Routing der Komponenten zu verfügen. Der Mikrokernel kommt mit drei IReleasePolicy Implementierungen:

     
      
  • AllComponentsReleasePolicy: alle Komponenten verfolgen korrekte Entsorgung auf der Microkernel-Instanz zur Verfügung
  • erzwingen   
  • LifecycledComponentsReleasePolicy: nur Track-Komponenten, die eine decommission Lebenszyklus assoziiert
  • haben   
  • NoTrackingReleasePolicy: führt kein Tracking
  •   
     

Sie können auch Ihre eigene Release-Politik mithilfe der Schnittstelle IReleasePolicy implementieren.

Was Sie vielleicht einfacher zu finden, ist die Richtlinie auf einen ändern NoTrackingReleasePolicy und dann behandeln die selbst entsorgen - dies auch potenziell riskant, aber wenn Ihr Lebensstil weitgehend vorübergehend (oder wenn, wenn der Behälter angeordnet ist, ist Ihre Anwendung über sowieso) ist es wahrscheinlich keine große Sache zu schließen. Denken Sie jedoch daran, dass alle Komponenten, die bereits mit dem Singleton injiziert worden sind, wird eine Referenz halten, so dass Sie könnte zu Problemen am Ende versuchen, Ihre Singletons „refresh“ - es ist wie eine schlechte Praxis scheint, und ich frage mich, ob vielleicht können Sie vermeiden, die dies geschieht in erster Linie durch die Verbesserung der Art und Weise Ihre Anwendungen zusammen.

Andere Ansätze sind eine benutzerdefinierte Lebenszyklus mit einer eigenen decommission Implementierung aufzubauen (so die Singleton-Freigabe tatsächlich der Komponente verfügen würde, ähnlich wie die vorübergehende Lebenszyklus der Fall ist).

Alternativ ein weiterer Ansatz ist es, einen Dekorateur für Ihren Dienst in dem Behälter mit einem Singleton Lebensstil registriert hat, aber Ihr tatsächlichen in dem Behälter registrierte zugrunde liegenden Service mit einem vorübergehenden Lebensstil - dann, wenn Sie die Komponente aktualisieren müssen nur die transienten entsorgen zugrunde liegende Komponente durch den Dekorateur gehalten und ersetzt sie durch eine frisch aufgelöste Instanz (lösen sie die Komponenten-Taste, anstatt den Dienst, bekommt die Dekorateur zu vermeiden) - diese Fragen mit anderen Singleton Diensten vermeidet (die nicht „aufgefrischt“ werden ) aus auf veraltete Dienste halten, die sie unbrauchbar machen entsorgt worden, aber ein bisschen Gießen usw. erfordert, damit es funktioniert.

Andere Tipps

Es hängt von der Lebensweise der Komponente, die Sie angeben, wenn Sie es in den Behälter gegeben.

Sie würden verwenden Release () Wenn der Lebensstil wird gepoolt. Dadurch wird die Komponente wieder in dem Pool für den nächsten Abruf (das Objekt nicht zerstört wird, so wäre schlecht, Entsorgung)

, wenn der Lebensstil vergänglich ist, wird ein neues Objekt erstellt wird, wenn Sie die Komponente erhalten. In diesem Fall ist die Entsorgung bis zu Ihnen, und Sie brauchen nicht Release zu rufen

Wenn die Lifestyle-Thema ist, wird die gleiche Komponente für jeden Thread verwendet wird, nicht zerstört wird.

Wenn der Lebensstil Singleton ist, nur eine Komponente erstellt wird und nicht detroyed.

Wahrscheinlich verwenden Sie transiente Komponenten? (Wenn Sie besorgt über in einer angemessenen Art und Weise zu entsorgen) in diesem Fall, wickeln Sie es nur mit einem mit und Sie werden eingestellt (oder die sich irgendwo entsorgen nennen)

using(ISomeService service = container.Resolve<ISomeService>())
{
 // Do stuff here
 // service.Dispose is automatically called 
}

Bearbeiten - Ja, um Ihre Singleton zu „aktualisieren“ oder entsorgen und neu erstellen Sie müßten entweder den Behälter zerstören oder einen benutzerdefinierten Lebenszyklus schreiben. einen benutzerdefinierten Lebenszyklus zu tun, ist eigentlich nicht so schwierig und hält die Logik so an einem Ort zu tun.

In Ordnung, also habe ich läuft Tests, und es scheint, wie Container.Release() implizit einen IDisposable des Dispose() Verfahren führt nur auszuführen, wenn der Lebensstil Transient ist (dies ist wahrscheinlich nicht ganz richtig, aber Punkt ist, dass es Gewohnheit‘eine verflixte Sache zu tun wenn der Lebensstil ist Singleton).

Nun, wenn Sie Container.Dispose() nennen wird es die Einweg-Methoden aufrufen, auch, leider wird es von der ganzen Kernel verfügen, und Sie werden alle Komponenten zurück in hinzufügen:

var container = new WindsorContainer();
container.AddComponentWithLifestyle<MyDisposable>(Castle.Core.LifestyleType.Singleton);
var obj = container.Resolve<MyDisposable>();  // Create a new instance of MyDisposable
obj.DoSomething();
var obj2 = container.Resolve<MyDisposable>();  // Returns the same instance as obj
obj2.DoSomething();
container.Dispose();  // Will call the Disposable method of obj
// Now the components need to be added back in   
 container.AddComponentWithLifestyle<MyDisposable>(Castle.Core.LifestyleType.Singleton);
var obj3 = container.Resolve<MyDisposable>();  // Create a new instance of MyDisposable

Zum Glück in meinem Fall kann ich mir leisten, nur alle Komponenten fallen und ich kann sie ziemlich leicht wiederherstellen. Dies ist jedoch suboptimal.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top