Ich habe ein Programm, das eine große Anzahl von Plugins verwenden muss.
Jedes Plugin muss eine sehr einfache Schnittstelle unterstützen, diese Schnittstelle wird in einer DLL definiert (IBaseComponent zur Vereinfachung der Frage).
Jedes Plugin befindet sich in einem bestimmten Verzeichnis (AppDirectory \ plugin \ plugin-type). Jedes Plugin kann einen beliebigen Namen für die DLL des Plugins haben (AppDirectory \ plugin \ plugin-type \ plugin-name.dll).
Also muss ich jedes Plugin-Unterverzeichnis durchsehen, jedes Plugin finden, das eine Klasse hat, die die IBaseComponent-Schnittstelle unterstützt, die Klasse instanziieren und einige Funktionen auf dem Plug-in aufrufen.
Ok, alles in Ordnung und Dandy, nichts davon ist besonders schwer. Das Problem ist jedoch, dass ich auf einige seltsame Probleme stoße.
Jedes Plugin muss die Base.dll-Datei in den einzelnen Plugin-Ordnern haben (statt nur in dem Programm, das das Plugin laden wird) und es scheint auch, dass ich viele Fehler und Warnungen bekomme, die eine DLL dynamisch laden DLLs, die auch geladen werden müssen.
Ich benutze:
%Vor%um die Plugin-DLL zu erhalten und zu verwenden:
%Vor%um die in der DLL enthaltenen Typen zu erfassen. Ich überarbeite die Typen und überprüfe, ob der einzelne Typ der IBaseComponent-Schnittstelle ist (was bedeutet, dass es sich um eine Klasse handelt, die zum Laden geeignet ist) mit:
%Vor%Später, um tatsächlich eine Instanz der Klasse aus der DLL zu erstellen, verwende ich:
%Vor%und dann verwenden:
%Vor%Um die Typen innerhalb des Moduls zu erhalten, wählen und laden Sie die Klasse, die die Schnittstelle unterstützt, wie oben.
Das Problem scheint zu sein, wenn ich Folgendes benutze:
%Vor%Wenn Sie tatsächlich versuchen, die Klasse zu laden, anstatt sie einfach anzusehen. (Daher meine unterschiedliche Verwendung von LoadFrom und ReflectionOnlyLoad )
Die Ausnahme, die ich beim GetTypes-Aufruf erhalte (bei einem zweiten Plug-in, aber niemals beim ersten!) ist:
%Vor%Mit der LoaderExceptions-Eigenschaft als:
%Vor%Ich bin mir nicht sicher, warum das passiert. Die DLL befindet sich im Plugin-Ordner und die DLL mit der IBaseComponent-Schnittstelle befindet sich ebenfalls in jedem der Plugin-Verzeichnisse. Gehe ich in die falsche Richtung?
Ist es auch erforderlich, dass ich eine Kopie der DLL mit IBaseComponent in jedem Plugin-Unterverzeichnis sowie diejenige, die vom Programm selbst verwendet wird, aufbewahre, oder mache ich etwas falsch, das mir erlauben würde, diese Anforderung zu entfernen?
Ich bin mir der MEF bewusst, was ich verwenden wollte, aber leider, weil ich dies auf .net 2.0 unterstützen muss. Ich kann MEF nicht benutzen.
Dies ist ein LoadLibrary () Fehler. Klingt für mich, dass Plugins eine Abhängigkeit von einigen nicht verwalteten DLLs haben. Ja, Windows wird es schwer haben, diese DLLs zu finden, es gibt keinen Grund, in den Plugin-Verzeichnissen nachzusehen. Vielleicht funktioniert es das erste Mal, weil das Standardverzeichnis Ihrer App zufällig auf das richtige Verzeichnis eingestellt ist. Um dies zu vermeiden, verwenden Sie Environment.CurrentDirectory.
Es ist entscheidend, genau herauszufinden, welche Abhängigkeiten nicht gefunden werden können. Nicht verwaltete werden nicht in fuslogvw.exe angezeigt, Sie können sie aus einer Ablaufverfolgung aus dem ProcMon-Dienstprogramm von SysInternals herausholen.