Frage

Ich möchte Ihnen einige der Erstellung von dynamisch ladbaren plugins in meiner software.Typische Weg, dies zu tun, ist die Verwendung der LoadLibrary WinAPI-Funktion, um eine dll zu laden und aufrufen GetProcAddress um einen Zeiger auf eine Funktion in die dll.

Meine Frage ist, wie kann ich dynamisch laden Sie ein plugin in C#/.Net-Anwendung?

War es hilfreich?

Lösung

Das folgende code-snippet (C#) erstellt eine Instanz von konkreten Klassen, die von Base gefunden in der Klasse Bibliotheken (*.dll) in den Pfad der Anwendung und speichert Sie in einer Liste an.

using System.IO;
using System.Reflection;

List<Base> objects = new List<Base>();
DirectoryInfo dir = new DirectoryInfo(Application.StartupPath);

foreach (FileInfo file in dir.GetFiles("*.dll"))
{
    Assembly assembly = Assembly.LoadFrom(file.FullName);
    foreach (Type type in assembly.GetTypes())
    {
        if (type.IsSubclassOf(typeof(Base)) && type.IsAbstract == false)
        {
            Base b = type.InvokeMember(null,
                                       BindingFlags.CreateInstance,
                                       null, null, null) as Base;
            objects.Add(b);
        }
    }
}

Edit: Die Klassen beziehen durch Matt sind wahrscheinlich eine bessere option .NET 3.5.

Andere Tipps

Als der .NET 3.5 gibt es eine formalisierte, baked-in-Möglichkeit zum erstellen und laden von plugins aus .NET-Anwendung.Es ist alles in der System.Add namespace.Für weitere Informationen können Sie aus diesem Artikel auf der MSDN-Website: Add-ins und Erweiterbarkeit

Das dynamische Laden von Plugins

Für Informationen, wie Sie dynamisch laden .NET-Assemblys finden Sie unter diese Frage (und meine Antwort).Hier ist ein code für die be-Schaffung einer AppDomain und laden einer assembly in es.

var domain = AppDomain.CreateDomain("NewDomainName");
var pathToDll = @"C:\myDll.dll"; 
var t = typeof(TypeIWantToLoad);
var runnable = domain.CreateInstanceFromAndUnwrap(pathToDll, t.FullName) 
    as IRunnable;
if (runnable == null) throw new Exception("broke");
runnable.Run();

Entladen Plugins

Eine typische Anforderung an ein plugin-framework ist zum entladen von plugins.Zu entladen dynamisch geladene Assemblys (z.B.plugins und add-ins) Sie haben das entladen der mit AppDomain.Weitere Informationen finden Sie unter dieser Artikel auf der MSDN-Website auf Anwendungsdomänen Entladen.

Mit WCF

Es ist ein stack-overflow-Frage und Antwort beschreiben, wie die Windows Communication Framework (WCF), um erstellen Sie eine plug-in-framework.

Bestehende Plug-in-Frameworks

Ich weiß von zwei plug-in-frameworks:

Einige Leute sprechen über die Managed Extensibility Framework (MEF) als plug-in oder add-in-framework, was es nicht ist.Weitere Informationen finden Sie unter diese StackOverflow.com Frage und diese StackOverflow.com Frage.

Ein Tipp ist, laden Sie alle plugins und so in eine eigene AppDomain, da der code ausgeführt werden kann, potenziell schädliche.Eine eigene AppDomain kann auch verwendet werden, um die "filter" - Assemblys und Typen, die Sie nicht laden möchten.

AppDomain domain = AppDomain.CreateDomain("tempDomain");

Und zum laden einer assembly, die in die Anwendung domain:

AssemblyName assemblyName = AssemblyName.GetAssemblyName(assemblyPath);
Assembly assembly = domain.Load(assemblyName);

Entladen der Anwendung domain:

AppDomain.Unload(domain);

Ja, ++ Matt und System.Add-in (ein zwei-Teil MSDN Magazin-Artikel über das System.Add-in verfügbar sind hier und hier).Eine weitere Technologie möchten Sie vielleicht zu schauen, um eine Idee zu bekommen, wo .NET Framework könnte in der Zukunft ist die Managed Extensibility Framework derzeit verfügbaren CTP-Formular auf Codeplex.

Grundsätzlich können Sie dies auf zwei weisen tun.

Die erste ist, zu importieren kernel32.dll und mit LoadLibrary und GetProcAddress, wie Sie es vor:

[DllImport("kernel32.dll")]

internal static extern IntPtr LoadLibrary(String dllname);

[DllImport("kernel32.dll")]

internal static extern IntPtr GetProcAddress(IntPtr hModule, String procname);

Das zweite ist, es zu tun in der .NETZ-Weise:mithilfe von reflektion.- Check-System.Reflection-namespace und die folgenden Methoden:

Zuerst laden Sie die Montage, indem es Weg, dann erhalten Sie den Typ (Klasse) aus, indem Sie den Namen, dann bekommen Sie die Methode der Klasse durch seinen Namen, wieder und schließlich rufen Sie die Methode mit den entsprechenden Parametern.

Der Artikel ist etwas älter, aber immer noch anwendbar für die Erstellung einer Erweiterbarkeit Schicht innerhalb der Anwendung:

Benutzern das Hinzufügen von Funktionalität zu Ihr .NET-Anwendungen mit Makros und Plugins

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