2009-10-10 5 views
5

Ich habe gerade die Inversion der Kontrolle (IOC) gelesen und es störte mich, dass es so aussieht, als ob es die Speicherverwaltung schmerzt. Natürlich scheint es, dass ioc hauptsächlich in Garbage-Collected-Umgebungen (Net, Java, Scripting) verwendet wird, während mein Interesse in nicht-gc-Einstellungen liegt.Kann die Inversion der Kontrolle und RAII zusammen spielen?

Meine Sorge hier ist, dass IOC in gewisser Weise gegen RAII geht, wie wir Ressourcenlebensdauer von Objektlebensdauer entkoppeln. Stört diese zusätzliche Komplexität niemanden? Und die eigentliche Frage, mit welchen Techniken lässt sich alles reibungslos machen?

+0

Siehe auch http://stackoverflow.com/questions/987761/how-do-you-reconcile-idisposable-and-ioc und http://unity.codeplex.com/Thread/View.aspx?ThreadId=38588 – TrueWill

Antwort

3

Aus diesem Grund habe ich meinen eigenen IoC-Behälter hergestellt, der (in C# /. NET) Einweg-Service-Wrapper zurückgibt, die bei der Entsorgung "das Richtige tun".

es:

  • nichts tun, wenn:
    • Das Objekt IDisposable
    • Ist das nicht Container-scoped (in diesem Fall behält der Behälter, den er und Return-Spur von nicht implementiert das gleiche Objekt mehr als einmal, und wenn der Container entsorgt wird, wird das Objekt auch)
    • Es ist nicht gepoolt
    • Es ist nicht Singleton -scoped (das gleiche wie Container-scoped, aber eine Hierarchie von Behältern wird die Singleton-scoped Dienst in dem obersten Container speichern)
  • Entsorgen des Dienstes (it Fabrik Umfang hat, und implementiert IDisposable)
  • Return es an den Pool

Dies bedeutet, dass der gesamte Code, die meine Dienste verwendet innerhalb eines using-Block ist, aber die Absicht ist klar, zumindest für mich:

using (var service = container.Resolve<ISomeService>()) 
{ 
    service.Instance.SomeMethod(); 
} 

im Grunde ist es sa ys: einen Dienst auflösen, SomeMethod für die Dienstinstanz aufrufen und dann den Dienst verwerfen.

Da dem Verbraucher nicht bekannt ist, ob die Dienstinstanz entsorgt werden soll oder nicht, gab es entweder die Wahl, IDisposable-Implementierungen ganz zu ignorieren oder alle Dienste zu veräußern, die IDisposable implementieren. Für mich war keine gute Lösung.Die dritte Option bestand darin, die Dienstinstanz in ein Objekt zu verpacken, das wusste, was mit dem Dienst zu tun war, sobald der Wrapper entsorgt wurde.

+0

Manchmal ist das Entschlüsseln von 'IDisposable' unvermeidlich (wie bei' foreach' auf einem Typ, der eine verwendbare 'GetEnumerator()' Methode implementiert, aber nicht 'IEnumerable 'implementiert), aber es ist ein wichtiger Geruch seit du Beachten Sie, dass eine Klasse einen Verweis auf etwas enthält, das "IDisposable" implementiert, bedeutet nicht immer, dass sie das Objekt besitzt, auf das sie sich bezieht. – supercat

0

Das erste, was mir einfiel, war SmartPointers. Und Vorlagenargumente. Aber ich bin mir nicht sicher, ob Template-Argumente als IOC-Technik zählen, obwohl ich denke, dass sie es sollten. Zumindest diese können einige Probleme mit IOC lindern, aber nicht vollständig auf der Idee verkauft werden.

1

Ja und nein. IoC entkoppelt die Ressourcenlebensdauer nicht von der Objektlebensdauer, es entkoppelt den Methodenaufrufbereich von der Objektlebensdauer - Sie möchten sehr oft, dass ein Objekt, das am Ende einer Methode zerstört werden würde, existiert, bis ein anderer IoC-Aufruf erfolgt. Daher müssen Sie entweder die Locals einer Methode in den Klassenbereich verschieben und sicherstellen, dass keine Methode in die Umgebung eindringt, oder eine andere Methode anwenden, z. B. eine zusätzliche "Umgebung" übergeben, um Objekten das Eigentum zu geben und sie zu zerstören in nachfolgenden IoC-Methodenaufrufen. Jeder Ansatz wird ziemlich kompliziert, wenn Sie ein allgemeines ereignisgesteuertes System wünschen - entweder müssen Ihre Modelle selbst explizite Rekursion und Iteration implementieren oder Ihr einfacher RAII C++ - Code wird schnell zu einem sehr komplexen Callback-Komplex - ausreichend komplex, dass ich aufgegeben habe auf C++ und RAII begann an kin stattdessen zu arbeiten.

Verwandte Themen