2016-07-30 25 views
0

Ich versuche, eine Plugin-Architektur zu bauen, wo DLLs in einer ZIP-Datei enthalten sind, dekomprimiert, gespeichert, dann so geladen, dass eine bestimmte Art kann mit gebaut und gearbeitet werden. In der Theorie klingt es machbar. Aber ich habe ein Problem damit. Ich bekomme immer eineWie eine Baugruppe zu laden und alle Arten in es mit C# erhalten (ohne Reflection)

ReflectionTypeLoadException.

Hier ist, was ich habe das nicht funktioniert:

 var dlls = pluginFiles.Where(p => p.Value.FileInfo.Extension.ToLower() == ".dll").ToList(); 
     int num = 0; 
     foreach(var dll in dlls){ 
      var assembly = Assembly.LoadFile (dll.Value.FileInfo.FullName); 
      var pluginTypes = assembly.GetTypes().Where (p => p.IsSubclassOf (typeof (Plugin))); 
      foreach(var pluginType in pluginTypes){ 
       var ctor = pluginType.GetConstructors().FirstOrDefault(); 
       if (ctor == null) continue; 
       var plugin = (Plugin)ctor.Invoke (new object [] { }); 
       if (plugin == null) continue; 
       num++; 
       _mgr.RegisterNew (plugin); 
      }      
     } 

Als ich durch diese in debug bin treten, geschieht die Ausnahme auf der Linie, wo ich assembly.GetTypes() renne.

Was mache ich hier falsch? Sollte ich etwas mit einer neuen AppDomain machen?

Weitere Informationen: Die Baugruppe, die ich lade, ist eine Testbaugruppe. Es hat einen Verweis auf FakeItEasy. Es hat eine einzige Klasse, die Klasse, nach der ich suche. Diese bestimmte Klasse ist eine Unterklasse einer anderen Klasse, die sich in einer Assembly befindet, auf die von meiner Aufrufklasse verwiesen wird ... Das sah verwirrend aus. Lassen Sie es mich so erklären:

Assembly 1: Kern, Montage 2: Dummy_assembly, Montage 3: Tests.

  • Beide Tests und Dummy_Montage Referenz Core.
  • Dummy_assembly ist eine DLL, die ich gezippt habe und versuche zu entpacken, zu laden und dann zu suchen.
  • Tests ist die Baugruppe, von der ich die oben gezeigte Methode aufrufen.
  • Der oben gezeigte Code befindet sich in Core.

Ich habe mir this angesehen. Es scheint, als ob es anwendbar sein könnte, aber ich kann nicht vollständig sagen, wie (und ich verstehe nicht ganz, warum diese Antwort für diese Frage funktioniert).

Antwort

0

Wenn die Anordnung eine Art umfasst, die nicht geladen werden kann, wird es (meistens weil auf einer unlösbaren Montag Referenz) wirft ... nichts kann dagegen getan werden.

Aber man kann die Ausnahme abfangen und die Typ Eigenschaft überprüfen und die Arten erhalten, die erfolgreich geladen werden kann.

https://msdn.microsoft.com/en-us/library/system.reflection.reflectiontypeloadexception.types(v=vs.110).aspx

Wenn Sie DLLs in einem anderen Verzeichnis verwiesen haben können Sie auch das AppDomain.AssemblyResolve Ereignis behandeln und diese selbst behandeln.

+0

Wie würde es mich behandeln? –

+0

https://msdn.microsoft.com/en-us/library/ff527268(v=vs.110).aspx – Jeff

0

Fügen Sie einen try/catch-Block um den gettypes-Code hinzu. Stellen Sie sicher, dass Sie sich an einem Speicherort anmelden, an dem Sie die Assembly nicht zu Debugzwecken laden konnten.