2012-08-08 18 views
6

Estoy intentando cargar algunos archivos .dll dinámicamente. Los archivos son complementos (auto-escritos por el momento) que tienen al menos una clase que implementa MyInterface. Para cada archivo que estoy haciendo lo siguiente:C# lanzar una clase a una lista de interfaz

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); 
      } 
     } 
    } 

La ejecución de esta causa una excepción de difusión, pero no puedo encontrar una solución. De todos modos, me pregunto por qué esto no funciona en absoluto. Estoy buscando una solución en .NET Framework 3.5.

Otra cosa que me ha pasado estaba null en p después de ejecutar lo siguiente en el punto antes de añadir una nueva entrada a _myList en el código anterior:

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

Este código fue el primer intento de cargar el Complementos, no encontré por qué p era null todavía. Espero que alguien me pueda guiar de la manera correcta :)

+1

este código no funciona, ¿qué es x y dónde lo inicias? – devundef

+0

En el fragmento de código anterior, ¿se supone que "x" en "if (x! = Null)" es "myI"? –

+0

También debe verificar que el tipo tenga un constructor predeterminado, ya que su código asume eso. –

Respuesta

4

Usted realmente debe leer Plug-ins and cast exceptions por Jon Skeet lo que explica el comportamiento que se ve y cómo hacer marcos de plug-in correctamente.

+0

Lo que pude sacar de él fue que el ensamblaje del complemento no es lo mismo que el ensamblaje de mi aplicación. – Phil

+0

Deseo que más personas voten esta, ya que creo que ese es probablemente el problema del OP. Básicamente, si piensas en esto como C++, y la definición de interfaz como un archivo .h, te encontrarás con este error. Si lo piensas en una forma de "tipos administrados", verás que hay dos interfaces, una por archivo, si se está compilando de la manera (incorrecta) que el enlace dice que podría ser. –

5

Hay una manera mucho más fácil de verificar si su tipo se puede convertir a su interfaz.

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); 
} 

Si IsAssignableFrom es falso, hay algo mal con su herencia, que es más probable causa de sus errores.

+0

bueno, sí, es 'falso'. Sin embargo, ahora solo tengo un miembro y realmente no sé qué podría estar mal con la herencia. – Phil

+0

¿Su conjunto "plugin" hace referencia al ensamblaje donde se define la interfaz? ¿El código de ejecución (código en la muestra) hace referencia al * mismo * ensamblaje? –

1

Mire el siguiente código. Creo que Type.IsAssignableFrom(Type type) puede ayudarte en esta situación.

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); 

} 
Cuestiones relacionadas