2012-08-08 12 views
6

Ich versuche, einige DLL-Dateien dynamisch zu laden. Die Dateien sind Plugins (für den Moment selbst geschrieben), die mindestens eine Klasse haben, die MyInterface implementiert. Für jede Datei, mache ich folgendes:C# übergibt eine Klasse an eine Schnittstellenliste

Dictionary<MyInterface, bool> _myList; 

    // ...code 

    Assembly assembly = Assembly.LoadFrom(currentFile.FullName); 
    foreach (Type type in assembly.GetTypes()) 
    { 
     var myI = type.GetInterface("MyInterface"); 
     if(myI != null) 
     { 
      if ((myI.Name == "MyInterface") && !type.IsAbstract) 
      { 
       var p = Activator.CreateInstance(type); 
       _myList.Add((MyInterface)p, true); 
      } 
     } 
    } 

Ausführen dieses eine gegossene Ausnahme verursacht, aber ich kann eine Abhilfe nicht finden. Jedenfalls frage ich mich, warum das überhaupt nicht funktioniert. Ich suche nach einer Lösung in .NET Framework 3.5.

Eine andere Sache, die mir passiert war die folgende an dem Punkt, nach dem Ausführen vor dem Hinzufügen eines neuen Eintrags in _myList in dem obigen Code null in p bekommen:

var p = type.InvokeMember(null, BindingFlags.CreateInstance, null, 
          null, null) as MyInterface; 

Dieser Code wurde der erste Versuch, die beim Laden Plugins, ich habe nicht herausgefunden, warum noch null war. Ich hoffe, jemand kann mich auf den richtigen Weg führen :)

+1

dieser Code funktioniert nicht, was ist x und wo Sie es init? – devundef

+0

In Ihrem obigen Code-Snippet ist "x" in "if (x! = Null)" wirklich "myI"? –

+0

Sie sollten auch überprüfen, dass der Typ einen Standardkonstruktor hat, da der Code davon ausgeht. –

Antwort

4

Sie wirklich Plug-ins and cast exceptions von Jon Skeet, die richtig das Verhalten erklären Sie sehen und wie zu tun Plug-in-Frameworks lesen sollten.

+0

Was ich herausnehmen konnte war, dass die Assembly des Plugins nicht mit der Assembly meiner Anwendung übereinstimmt. – Phil

+0

Ich wünschte, mehr Leute würden dieses eine wählen, da ich denke, dass das das OP-Problem ist. Wenn Sie sich das wie C++ vorstellen und die Interface-Definition wie eine .h-Datei, dann werden Sie auf diesen Fehler stoßen. Wenn Sie es auf eine "verwaltete Art" Weise denken, werden Sie sehen, dass es zwei Schnittstellen gibt, eine pro Datei, wenn sie so kompiliert wird, wie es der Link sagt. –

5

Es gibt viel einfacher zu prüfen, ob Ihr Typ an Ihre Schnittstelle gegossen werden kann.

Assembly assembly = Assembly.LoadFrom(currentFile.FullName); 
foreach (Type type in assembly.GetTypes()) 
{ 
    if(!typeof(MyInterface).IsAssignableFrom(type)) 
     continue; 

    var p = Activator.CreateInstance(type); 
    _myList.Add((MyInterface)p, true); 
} 

Wenn IsAssignableFrom falsch ist, es ist etwas falsch mit Ihrem Erbe, die wahrscheinlichste Ursache für Ihre Fehler ist.

+0

gut ja, es ist 'false'. Allerdings habe ich jetzt nur ein Mitglied und weiß wirklich nicht, was mit der Erbschaft falsch sein könnte. – Phil

+0

Bezieht sich Ihre "Plugin" -Assembly auf die Assembly, in der die Schnittstelle definiert ist? Bezieht sich Ihr laufender Code (Code in Beispiel) auf * gleiche * Assembly? –

1

Bitte schauen Sie in den folgenden Code. Ich denke, Type.IsAssignableFrom(Type type) kann Ihnen in dieser Situation helfen.

Assembly assembly = Assembly.LoadFrom(currentFile.FullName); 
///Get all the types defined in selected file 
Type[] types = assembly.GetTypes(); 

///check if we have a compatible type defined in chosen file? 
Type compatibleType = types.SingleOrDefault(x => typeof(MyInterface).IsAssignableFrom(x)); 

if (compatibleType != null) 
{ 
    ///if the compatible type exists then we can proceed and create an instance of a platform 
    found = true; 
    //create an instance here 
    MyInterface obj = (ALPlatform)AreateInstance(compatibleType); 

} 
Verwandte Themen