27 Stimmen

Verwendung von Ninject in einer Plugin-ähnlichen Architektur

Ich lerne gerade DI und habe kürzlich mein erstes Projekt gemacht.

In diesem Projekt habe ich das Repository-Muster implementiert. Ich habe die Schnittstellen und die konkreten Implementierungen. Ich frage mich, ob es möglich ist, die Implementierung meiner Schnittstellen als "Plugins", dlls zu bauen, die mein Programm dynamisch laden wird.

So kann das Programm im Laufe der Zeit verbessert werden, ohne dass man es neu erstellen muss. Man legt einfach die dll in den "plugins"-Ordner, ändert die Einstellungen und voilá!

Ist dies möglich? Kann Ninject in diesem Fall helfen?

0voto

Joseph Ferris Punkte 12354

Es gibt mehrere Möglichkeiten, dies zu tun, und Sie haben bereits das Hauptziel erreicht, indem Sie konkrete Implementierungen durch vordefinierte Schnittstellen haben. Realistischerweise sollten Sie, wenn Ihre Schnittstellen stabil bleiben, in der Lage sein, auf Ihrer Kernanwendung aufzubauen.

Ich bin mir jedoch nicht sicher, wie die Implementierung mit Ninject funktionieren würde. Sie können dies mit dem Anbieter-Modell oder mit Reflexion - obwohl ich denke, dass die Reflexion übertrieben ist, wenn man sie nicht unbedingt braucht.

Beim Providermodell-Ansatz platzieren Sie die Datei im Ordner /bin oder einem anderen Ordner, den Sie untersuchen, und passen die .config-Datei so an, dass sie das Vorhandensein des Providers widerspiegelt. Wenn Sie einen bestimmten "Plugin"-Ordner haben, können Sie eine Methode erstellen, die beim Starten der Anwendung und ansonsten regelmäßig aufgerufen wird, um nach neuen oder entfernten Instanzen zu suchen und die Anbieter neu zu laden.

Dies würde in ASP.NET, unter C# oder VB funktionieren. Wenn Sie jedoch eine andere Anwendung erstellen, müssen Sie einen anderen Ansatz in Betracht ziehen. Der Anbieter ist eigentlich nur Microsofts Weiterentwicklung der Strategie-Muster .

0voto

Ruben Bartelink Punkte 57310

Ich habe dies als Treffer für Activator.CreateInstance + Ninject erhalten und wollte nur auf etwas in diesem Bereich hinweisen - hoffentlich inspiriert es jemanden dazu, eine echte Killer-Antwort auf diese Frage auf SO zu finden.

Wenn Sie sich noch nicht die Mühe gemacht haben, Module und Klassen automatisch zu scannen und bei Ninject zu registrieren, und Ihr Plugin immer noch über Activator.CreateInstance erstellen, dann können Sie die Abhängigkeiten nach dem Erstellen der Instanz über

IKernel k = ...
var o = Activator.CreateInstance(...);
k.Inject( o );

Natürlich wäre dies nur eine vorübergehende Lösung auf dem Weg zu etwas wie http://groups.google.com/group/ninject/browse_thread/thread/880ae2d14660b33c

0voto

Hùng Lê Xuân Punkte 215

Ich denke, dass kein Rahmen notwendig ist. Dieses Tutorial ist Ihr Problem gelöst http://www.codeproject.com/KB/cs/c__plugin_architecture.aspx

-1voto

Patrick Desjardins Punkte 130529

Das Problem ist, dass Sie möglicherweise neu kompilieren müssen, wenn das Objekt, das Sie beim Laden Ihres Moduls eingerichtet haben, innerhalb des Programms verwendet wird. Der Grund dafür ist, dass Ihr Programm möglicherweise nicht die neueste Version der Assembly Ihrer Klasse hat. Wenn Sie beispielsweise eine neue konkrete Klasse für eine Ihrer Schnittstellen erstellen, ändern Sie die Plugin-DLL. Der Injector lädt sie, aber wenn sie in Ihrem Programm zurückgegeben wird (kernel.get(...)), hat Ihr Programm möglicherweise die Assembly nicht und gibt einen Fehler aus.

Ein Beispiel dafür, wovon ich spreche:

BaseAuto auto = kernel.Get<BaseAuto>();//Get from the NInjector kernel your object. You get your concrete objet and the object "auto" will be filled up (interface inside him) with the kernel.

//Somewhere else:

public class BaseModule : StandardModule
{
        public override void Load(){
            Bind<BaseAuto>().ToSelf();
            Bind<IEngine>().To<FourCylinder>();//Bind the interface
        }     
 }

Wenn Sie einen neuen FourCylinder mit dem Namen SixCylinder erstellt haben, wird Ihr echtes Programm keinen Bezug zu Ihrem neuen Objekt haben. Sobald Sie also das BaseModule.cs aus dem PlugIn laden, könnten Sie Probleme mit der Referenz bekommen. Um dies zu beheben, müssen Sie die neue DLL dieser konkreten Implementierung mit Ihrem Plugin verteilen, das das Modul enthält, das Injector benötigt, um die Klasse Interface to Concrete zu laden. Dies kann ohne Probleme gemacht werden, aber Sie fangen an, eine ganze Anwendung zu haben, die auf dem Laden vom Plugin basiert und das könnte in einigen Punkten problematisch sein. Seien Sie sich dessen bewusst.

ABER, wenn Sie einige PlugIn-Informationen benötigen, können Sie diese bekommen Lernprogramm von CodeProject .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X