Frage

Ich bin mit Schloss windsor für ein Haustier-Projekt arbeite ich an. Ich fange an zu bemerken, dass ich brauche die IoC-Container an verschiedenen Orten in meinem Code nennen neue Objekte zu erstellen. Diese Abhängigkeit von dem Behälter macht meinen Code schwerer zu halten.

Es gibt zwei Lösungen, die ich verwendet habe, um dieses Problem zu lösen

habe ich versucht, um die Behälter abstrakte Fabriken als Wrapper zu erstellen, die ich in Teile meiner Anwendung injizieren könnte, die Objekte erstellen müssen. Das funktioniert aber hat einige Nachteile, weil Burg eine harte Zeit, seinen eigenen Behälter als Abhängigkeit Injektion hat. Also muss ich tun, dass von Hand, diese Art von Niederlagen der ganze Zweck des IoC-Container.

Ich habe die Hauptapplication Klasse wickeln Sie die IoC-Container und Arbeit als zentrales Werk / Repository verwendet. Das war ziemlich succesfull aber diese Klasse ist immer zu groß und wirkt wie ein zentraler Gott Objekt, fast alle andere Objekte haben einen Verweis auf mich.

Beide Lösungen Art von Arbeit, aber beide haben ihre Nachteile. Also ich bin gespannt, ob andere Leute das gleiche Problem hatten und haben bessere Lösungen gefunden.


Bearbeiten Das Problem ist nicht für Objekt A, das hier Objekt B. hängt in der Regel ich nur Konstruktor Injektion und alles funktioniert verwenden. Manchmal habe ich Objekte vom Typ A, die eine variable Anzahl von anderen Objekten des Typs B während ihrer Lebensdauer zu schaffen brauchen. Ich bin mir nicht sicher, wie dies zu tun.

@Blair Conrad: Die Wartungsprobleme sind nicht schwerwiegend, bis jetzt. Ich hatte einige Klassen hängen von der Container-Objekt aufrufen container.Resolve <>. Und ich möchte nicht mein Code haben, je nachdem, was ich denke, Infrastruktur ist. Ich bin immer noch Dinge zu versuchen, so bemerkte ich, ich hatte eine Menge Code zu ändern, wenn für dieses Projekt von ninject zum Schloss wechseln.

@flowers: Hmm. Ich mag deine Fäuste Lösung. Es verbindet die Dinge, die von beiden Lösungen arbeiten habe ich versucht. Ich glaube, ich war noch zu viel in Objekten zu denken und nicht genug in Schnittstellen / Verantwortung. Ich habe versucht, bauten Fabriken Zweck, aber ich mag sie den Behälter hinter den Kulissen verwenden, um die Objekte zu erstellen und ich havn't herausgefunden, wie ich kann, DI die Behälter in Objekte in einer sauberen Art und Weise.

War es hilfreich?

Lösung

Der Hauptvorteil von Dependency Injection, zumindest in meinen Anwendungen ist die Möglichkeit, Code zu schreiben, den Kontext Agnostiker ist. Aus dieser Perspektive scheint Ihre zweite Lösung, wie es wirklich der DI Nutzen gräbt Sie geben könnte. Wenn das ‚Gott-Objekt‘ verschiedene Schnittstellen zu jeder Klasse setzt auf der es verweist, kann es nicht zu schlecht sein. Aber wenn man so weit ging ich sehe nicht, warum Sie nehmen Sie es nicht den ganzen Weg auf den Reifen.

Beispiel: Ihr Gott-Objekt hat einen getFoo () -Methode und eine GetBar () -Methode. Objekt A muss ein Foo, Objekt B eine Bar braucht. Wenn A nur ein Foo muss, sollte Foo direkt in A injiziert werden und A sollte nicht bewusst von Gott sein. Aber wenn A zu halten braucht Foos zu schaffen, A einen Verweis auf Gott gibt, ist ziemlich unvermeidlich. Aber man kann sich von dem, indem man Gott um durch Verengen der Art des Verweises auf Gott verursachten Schaden schützen. Wenn Sie Gott FooFactory machen implementieren und A einen Verweis auf die FooFactory von Gott umgesetzt geben, können Sie immer noch den Code in A in einem Kontext neutral schreiben. Das verbessert die Möglichkeiten für die Wiederverwendung von Code und erhöht das Vertrauen, dass eine Änderung zu Gott wird nicht unerwartete Nebenwirkungen verursachen. Zum Beispiel können Sie sicher sein, wenn GetBar () von Gott zu entfernen, dass die Klasse A wird nicht brechen.

ABER ... wenn du gehst, diese Schnittstellen alle sowieso haben, sind Sie wahrscheinlich besser dran zu schreiben Zweck gebauten Werk Klassen und Verdrahtung alle Objekte zusammen, Fabriken enthalten, innerhalb des Behälters, anstatt den Behälter Einwickeln überhaupt. Der Behälter kann nach wie vor die Fabriken konfigurieren.

Andere Tipps

Bitte, nicht immer immer statische Klassen wie IoC.Container.Resolve oder ContainerFactory.GetContainer verwenden!

Das macht den Code komplizierter, schwieriger zu pflegen, um zu testen, wiederzuverwenden und zu lesen.

Normalerweise jede einzelne Komponente oder eine Dienstleistung hat nur einen einzigen Punkt der Injektion - das ist der Konstruktor (mit optionalen Eigenschaften). Und in der Regel Ihre Komponenten oder Serviceklassen sollten nicht immer über die Existenz von so etwas wie Container wissen.

Wenn Ihre Komponenten wirklich dynamische Auflösung innen haben müssen (dh der Ausnahmebehandlung Politik oder Workflow-Lösung, basierend auf dem Namen), dann empfehle ich Kreditvergabe IoC Kräfte über den hochspezifische Anbieter

Während ich die Eindeutigkeit von „speziell dafür gebauten Fabriken“ zu schätzen und sie auch selbst verwenden, fühlt sich dies wie ein Code Geruch in meinem eigenen Design, da die öffentliche Schnittstelle (kleine „i“) hält mit einer neuen Fabrik zu ändern und / oder einem neue GetX Methode für jede Implementierung. Jeremy Miller Nach der Lektüre Es ist Zeit für IoC Container Detente , vermute ich, Generika und Einspritzen des Behälters selbst ist der Weg zu gehen.

Ich würde wickeln Ninject, StructureMap oder Windsor in einer Art IServiceLocator Schnittstelle wie die in Jeremys Artikel vorgeschlagen. hat dann einen Container Fabrik, die einfach eine IServiceLocator überall in Ihrem Code gibt, auch in Schleifen wie ursprünglich vorgeschlagen.

IServiceLocator container = ContainerFactory.GetContainer(); 
while( keepLooping )
{
    IExample example = container.GetInstance<IExample>();
    keepLooping = example.DoWork();
}

Ihre Container Fabrik kann immer die gleiche intance zurückkehren, können Sie IoC Frameworks tauschen, was auch immer.

Als Follow-up zu @flipdoubt

Wenn Sie am Ende einen Service Locator Typ Muster verwenden Sie können http heraus zu überprüfen: // www. codeplex.com/CommonServiceLocator . Es hat einige Bindungen zur Verfügung zu mehreren populären IoC Frameworks (windsor, StructureMap), die hilfreich sein könnten.

Viel Glück.

Ich würde in diesem Fall empfehlen stark typisierte Fabriken verwenden, wie Sie erwähnt, die injiziert bekommen. Diese Fabriken können die Behälter wickeln, kann aber erlauben in zusätzlichen Kontext vorbei und machen zusätzliche Handhabung. Zum Beispiel könnte das Erstellen auf dem OrderFactory kontextuelle Parameter akzeptieren.

Mit statischen Abhängigkeiten auf einem generischen Service Locator ist eine schlechte Idee, wie Sie die Absicht und Kontext verlieren. Wenn ein IoC eine Instanz aufbaut, kann es die richtigen Abhängigkeiten von einer Vielzahl von Faktoren liefern wie proifle, Kontext, usw., wie es das große Bild hat.

CommonServiceLocator ist für diesen Zweck nicht, wenn man es zu benutzen versucht sein könnte. Der Hauptzweck für CommonServiceLocator ist für apps / Frameworks, die Quer IoC-Container-kompatibel sein soll. Allerdings Apps, die den Locator nur dann optimal, wenn rufen Sie verwenden sollten, um eine Hierarchie von Komponenten und deren dependenices aufzubauen. Es sollte nie direkt wieder aufgerufen werden. Wenn wir eine Möglichkeit hatten zu erzwingen, dass wir haben würde. In Prism ( http://www.microsoft.com/compositewpf ) haben wir eine IContainerFacade für den Aufbau Module. Das ist ein Service Locator obwohl ein niedriges Niveau ein. Im Nachhinein sollten wir wahrscheinlich ein oder etwas module und IContianerFacade verwendet erstellt haben ein halten sie zu bekommen, und verwenden dann, dass die Entschlossenheit Module vs direkt an die Fassade geht. Hinterher ist 20 / 20. Es ist niedriges Niveau genug aber, dass es nicht wirklich die Dinge nicht beeinträchtigt.

Auf CSL, rangen wir mit der Namensgebung, weil es zu Verwirrung führen könnte. Am Ende entschieden wir uns für CSL weil technisch die Schnittstelle nicht für Sie DI zu tun.

Das ist ein wirklich comon Problem. Windsor gebaut ist in typisierten Fabrik Einrichtung geben die Vorteile einer Fabrik zu verwenden, ohne die genannten Nachteile.

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