2010-02-11 11 views
8

Ich habe eine Klasse, die Abhängigkeiten hat, die ich mit Ninject verdrahtet habe.Ninject-Kernel-Erstellung in einer Klassenbibliothek

In der realen Implementierung verwende ich Property-Injektion, aber nur um schnell zu veranschaulichen, werde ich auf dem Feld injizieren. Wie ich verstehe, statt newing Instanzen von MyObject, um die Abhängigkeiten zu erhalten, um richtig injiziert werden, muss ich jedoch

kernel.Get<MyObject>() 

Das, was ich bin Stolpern auf verwenden, ist, dass MyObject wird nur in die verwendet werden, Kontext einer Klassenbibliothek. Die Absicht ist, dass Endanwendungen ihre eigenen Module erstellen und sie in eine Kernel-Instanz zum Hydratisieren übergeben. Ist das der pragmatischste Weg, um eine generische Instanz eines Ninject-Kernels auf meine Klassenbibliothek zu bringen, damit Instanzen von MyObject (und anderen ähnlichen Fällen) hydratisiert werden können?

Meine erste Neigung ist eine Art Fabrik, die einen Singleton-Kernel internalisiert - was die Anwendungen selbst hydratisieren/initialisieren müssen, indem sie ein Modul laden.

So in RandomService.cs

var myKernel = NinjaFactory.Unleash(); 
var myobj = myKernel.Get<MyObject>(); 
myobj.foo(); 

Bevor ich aber zu weit auf diesem Weg gehen, ich brauche eine Plausibilitätsprüfung zu tun, um sicherzustellen, dass das Denken Sound ist oder dass es nicht einige offensichtlich andere was ich vermisse. Ich bin offensichtlich neu in IoC und fühle mich wie ich die Grundlagen, aber nicht unbedingt die besten realen Möglichkeiten, es zu verwenden.

Antwort

9

Ich bin mir nicht sicher, ob ich alle Details in Ihrer Frage verstehe, aber soweit ich verstehe, fragen Sie, wie Sie die Abhängigkeit von Ninject externalisieren können.

Es ist möglich, DI-friendly libraries without ever referencing any particular DI Container (Ninject oder irgendetwas anderes) zu schreiben. Dies lässt den Verbraucher der Bibliothek offen, um den DI-Behälter seines oder ihres Geschmacks zu wählen (oder überhaupt keinen Behälter zu verwenden). Dieser Ansatz ist sehr bevorzugt, da er einen größeren Freiheitsgrad bietet.

Allerdings sollten Sie wirklich Constructor Injection über Property Injection begünstigen. Obwohl Property Injection täuschend einfach zu implementieren scheint, ist es ziemlich schwierig, es richtig zu machen.

Einer der großen Vorteile von Constructor Injection besteht darin, dass Sie dem Konstruktor keine Attribute hinzufügen müssen, da er strukturell bereits alle Informationen enthält, die ein DI-Container zum korrekten Verdrahten benötigt.

+0

Glücklicherweise ist dies eine interne (in einem Unternehmens Sinne) Lib, so habe ich ein in sich geschlossenes Publikum - andere Entwickler in meinem Team, mit einem Standard-Tool. Nun kann jeder Entwickler unterschiedliche Bindungen haben, die er will, daher meine ursprüngliche Quandry. Re: ctor vs Prop-Injektion, Requisite scheint sicherlich eine Menge Gruft haben Ich muss schreiben, aber ich sorge mich um die Abhängigkeitsliste wächst im Laufe der Zeit und damit die CTor Anrufe. Gibt es andere Nachteile für die Injektion, auf die ich achten sollte? – bakasan

+2

Auch mit einer internen App würde ich immer noch die gleichen Prinzipien befolgen, da sie zu sauberer Code mit besserer Trennung von Bedenken führen. Es gibt viele potenzielle Probleme mit Property Injection, einschließlich der Schutz Invarianten (ist die Abhängigkeit Null?), Möglicherweise Hot-Swapping der injizierten Abhängigkeit (wahrscheinlich nicht etwas, was Sie tun möchten) und eine vage API im Allgemeinen. –

+2

Oh, und nur um vorne und explizit darüber zu sein: Ich halte Service Locator ein Anti-Muster: http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx –

4

Marks Punkt ist definitiv meine Startansicht (daher ein +1) darauf. NB vergessen Sie nicht, seinem Link zu folgen.

Ich für einen war in der Vergangenheit schuldig, Konstruktor über Eigenschaften (oder Felder) zu früh aufzugeben (meine "Entschuldigung" war, dass als eine Basisklasse 5 Eigenschaften brauchte ich nicht alle abgeleiteten Klassen damit belasten wollte) Die Lösung bestand darin, die 5 Eigenschaften, die in einer Klasse oder Hierarchie von Klassen involviert sind, zu umhüllen, die die zugrundeliegenden Konzepte darstellen, die die Eigenschaften repräsentieren, ein bisschen wie das Refactoring des Einführen von Parameterobjekten.

Eine gute Diskussion der Überlegungen ich http://thinkbeforecoding.com/post/2009/05/15/IOC-container-go-hide nützlich ist gefunden (kippe die SO Post liegen, dass sie und einige Themen um es erwähnt, vielleicht hat jemand einen Link zu injizieren: D)

Ein weiterer Blog, dass einige fasst diese Punkte sind Your IoC Container is Showing

Und http://davybrion.com/blog/2009/11/integrating-your-ioc-container-with-agatha/

0

Hier ist ein schönes Allzweck-Rezept für alle ninject Module in der aktuellen Baugruppe zu finden:

IKernel _serviceKernel = new StandardKernel(); 

Assembly myAssembly = this.GetType().Assembly; 

IEnumerable<Type> ninjectModuleTypes = 
    myAssembly.GetTypes().Where(type => type.BaseType == typeof(NinjectModule)); 

foreach (Type ninjectModuleType in ninjectModuleTypes) 
{ 
    NinjectModule mod = (NinjectModule)Activator.CreateInstance(ninjectModuleType); 
    _serviceKernel.Load(mod); 
} 
Verwandte Themen