2009-11-04 7 views
9

Ich erstelle eine kleine C# -Anwendung, die derzeit aus einer Kernbaugruppe und einer Winforms-Baugruppe besteht. Mir ist klar, dass ich Ninject in einer kleinen Sache wahrscheinlich nicht wirklich brauche, aber ich würde es gerne ausprobieren.C#, Ninject: Wo setzt du den Kernel und deine Module?

Egal, um mit Ninject zu arbeiten Ich habe verstanden, dass Sie eine Reihe von Modulen schreiben würde, welche Karten Klasse zurückgegeben wird und so weiter. Danach erstellen Sie eine Instanz von IKernel und laden Sie Ihre Module in diese.

Aber wo behalte ich diese Module? Und wo behalte ich den Kernel? Wohin geht das Zeug?

Antwort

3

Sie können eine statische Wrapper-Klasse für den Kernel erstellen. Auf diese Weise können Sie etwas wie ServiceLocator.Resolve()

Für die Registrierung von Diensten gibt es zwei Möglichkeiten: Inline-und Modulregistrierung. Beide sollten beim Bootstrapping geladen werden. Modul ist besser zum Organisieren.

Vielleicht wäre es einfacher mit StructureMap zu starten, da es eine statische Klasse gibt und Auto Mapping-Funktionen.

Diese Screencasts sollte Ihnen den Start:

3

+ 1'd Marek Antwort - auf jeden Fall diese Ressourcen schauen.

Einige Punkte ...

Sie sind auf jeden Fall Recht, dies zu versuchen, auch in einer kleinen App. Es ist auch wichtig, über oberflächlich einfache Fragen nachzudenken, wie die, die Sie gestellt haben. Für DI muss man wirklich etwas damit anfangen, um es wirklich zu schätzen - ich für eine Zeit war in der "Oh, ich habe nur eine kleine App" (Verweigerung) Lager für eine lange Zeit, bis ich es tatsächlich verwendet .

Es gibt eine Schule von, die im Allgemeinen sollte weg von Service Locator sein und gerade Injektion [ohne irgendwelche Abhängigkeiten zu einem Container].

Wenn Sie nicht Service Locators verwenden, muss niemand wissen, wo der Container (Kernel) ist, was das Beste ist.

Module sind hauptsächlich für die Zwecke der Kompartimentierung Chargen von Dingen in einem bestimmten Gesamtcontainer (Kernel) zu registrieren.

Sicher gibt es eine kanonische 'Global Container' Singleton-Implementierung für Ninject da draußen? EDIT: gefunden Nur ein: - http://www.codethinked.com/creating-a-binding-factory-for-ninject

Siehe auch Ninject: How do I inject into a class library?

+0

Ich war nur auf der Suche nach einem kanonischen Weg, dies zu tun und dachte "großartig!" Als ich dich sah, verknüpfte ich einen. Schlechte Nachrichten, dieser Code ist TERRIFICally UNTHREADSAFE. Wenn ich den Kernel in einen Singleton verpacken soll, kann ich das selbst auf sichere Weise tun (Hinweis, statischer Konstruktor), aber sei gewarnt, alle, die in Zukunft hierher kommen: Dieser Link-Artikel ist eine komplett nicht threadsichere Implementierung. –

+0

@JimmyHoffa Ich stimme zu, dass es nicht threadsafe ist (schlagen Sie vor, einen Ansatz Ihrer Wahl von http://csharpindepth.com/articles/general/singleton.aspx anzuwenden). Aber viel besser als das ist es, mit dem Hauptpunkt meiner Antwort zu gehen, nämlich eine Kompositionswurzel zu haben, die einen klaren Platz hat, wo die Initialisierung stattfinden kann, um die Notwendigkeit für diese Threadsicherheit (neben anderen Problemen) aus dem Bild zu nehmen vollständig. –

+0

Ich bin nicht vertraut mit Ihrer Komposition root, aber ohne Zugriff auf den Kernel, wie fordern Sie Objekte, denen der Konstruktor injiziert werden soll? in Ihrer UI möchten Sie Zugriff auf Ihren 'UserManager', der ein' IUserRepository' bei der Erstellung benötigt; Wie bekommst du diesen 'UserManager' ohne Zugriff auf den Kernel (durch so etwas wie einen Service-Locator)? Sie können nicht einfach 'new UserManager (???);' und erwarten, dass das Richtige an den Konstruktor übergeben wird, oder? –

0

Mein Standpunkt: wie Marek sagte, sollten Sie einige (wahrscheinlich statisch) Wrapper für die Kernel erstellen, die die iKernel Instanz enthält. Es sollte die Methode < T> und wahrscheinlich die Methode Load (INinjectModule-Modul) enthalten - alle statisch.

In jeder Baugruppe können Sie einfach Ihr eigenes INinjectModule definieren, das Klassen innerhalb dieser Baugruppe abbildet.

Der Kernel-Wrapper befindet sich in der "niedrigsten", der gebräuchlichsten Assembly (normalerweise die, in der sich Log und Utils befinden). Das liegt daran, dass Kernel von allen Teilen aus zugänglich sein muss - also muss es in der Assembly sein, auf die alle anderen verweisen. Wenn Sie keinen haben, sind Sie immer frei genug, um einen zu erstellen. Dies mag ein wenig schwierig erscheinen, man könnte erwarten, dass Kernel in der 'höchsten' Assembly (der ausführbaren) sein wird. Nicht wahr.

Um alle Ihre Module aus Ihren Baugruppen zu registrieren, rufen Sie einfach Kernel.Load (neues XXModule) in jedem von ihnen auf.