2008-10-03 6 views
6

Estoy intentando cargar ensamblajes en un dominio de aplicación separado, pero me encuentro con un problema muy extraño. Aquí hay algo de código:Cargando ensamblajes en AppDomain por separado, obteniendo InvalidCastException

public static void LoadAssembly(string assemblyPath) 
    { 

     string pathToDll = Assembly.GetCallingAssembly().CodeBase; 
     AppDomainSetup domainSetup = new AppDomainSetup 
     { 
      PrivateBinPath = pathToDll 
     }; 

     AppDomain newDomain = AppDomain.CreateDomain("AssemblyLoader",null,domainSetup); 


     AssemblyLoader loader = (AssemblyLoader)newDomain.CreateInstanceFromAndUnwrap(
      pathToDll, 
      typeof(AssemblyLoader).FullName); 

    } 

AssemblyLoader es otra clase en el mismo conjunto como éste, y se hereda de MarshalByRef, sin embargo, por alguna extraña razón, me sale una excepción de lanzamiento cada vez que trato de ejecutar este. Incluso codifiqué la ruta a la DLL en lugar de usar GetCallingAssembly(). CodeBase, pero sigo recibiendo esta excepción.

Entiendo que es difícil responder a una pregunta como esta sin realmente verla y tener más información, pero tal vez alguien se haya encontrado en una situación similar y conozca los "errores" comunes y lo que debería tener en cuenta.

EDITAR: El motivo por el que no deseo cargarlo directamente es porque esto es solo parte del código. El objetivo final es que esta clase tenga un método que cargue ensamblajes, obtenga su GUID y otra información sobre ellos y los almacene en una base de datos para un proyecto en el que estoy trabajando. Por lo tanto, si cargo este ensamblado en un dominio de aplicación separado, también puedo cargar los otros allí y luego descargar el dominio de la aplicación. No tiene sentido tener todos estos ensamblajes cargados durante toda la aplicación, si solo necesito esos datos.

+0

Si la clase AssemblyLoader está en el mismo ensamblaje que esta, ¿por qué intenta cargarla desde newDomain? ¿Por qué no simplemente crear una instancia directamente? –

+1

Es una forma de cargar plugins indirectamente. Si la instancia del cargador está en el dominio principal de la aplicación, usted crea una versión en un dominio de aplicación extranjera y le pide que cargue los complementos que le interesen. Esto evita que sus complementos necesiten saber si son capaces de ser manejado por un dominio de aplicación separado. (es decir, deriva de MarshalByRefObject) Esto mantiene flexibles las decisiones de diseño (por ejemplo, crea una clase base de complemento que proporciona todas las funcionalidades compartidas para los complementos). –

Respuesta

0

No creo que la configuración de PrivateBinPath sea necesaria, más allá de eso, no es necesario usar la ruta de acceso a la DLL, sino el nombre completo del ensamblado para el primer parámetro; Proveedores:

AssemblyLoader loader = (AssemblyLoader)newDomain.CreateInstanceFromAndUnwrap(
     typeof(AssemblyLoader).Assembly.FullName, 
     typeof(AssemblyLoader).FullName); 
+1

Respuesta incorrecta. El primer parámetro CreateInstanceFromAndUnwrap() es una ruta de acceso y un nombre de archivo, no un nombre de ensamblaje.CreateInstanceAndUnwrap(), sin embargo, es un nombre de ensamblado, pero eso no ayuda al asker porque simplemente resolvería la misma ruta y nombre de archivo. – Timwi

+0

http://msdn.microsoft.com/en-us/library/y7h7t2a2.aspx – TheXenocide

2

(EDIT: después de leer la excepción dada, el cambio de respuesta completamente)

Parece que el problema es la llamada CreateInstanceFromAndUnwrap, que utiliza la semántica de LoadFrom 'PathToDll'. Suzanne Cook detailed the possible sticking point en su blog donde su AppDomain original intenta llamar a Load ("SomeAssembly, [...]") en lugar de LoadFrom ("pathToDll") cuando intenta resolver el tipo en cuestión.

Su consejo fue enlazar el evento AssemblyResolve en el dominio actual para hacer la LoadFrom correcta para obtener el tipo. Un poco de búsqueda de google apunta a a possible solution to the problem según la sugerencia de Suzanne.

+0

No, esto es lo que está diciendo: No se puede convertir proxy transparente al tipo 'CompanyNamespaceTakenOut.AssemblyLoader – BFree

+0

Actualizado para reflejar eso. – user7116

0

Salida this article.

Utilizando el código en ese artículo me dieron un objeto de aplicación entre dominios. Resumí las cosas un poco con genéricos y tengo tres ensamblajes. (es decir, 1 define la interfaz, 1 define la implementación del complemento y el programa principal que le dice al genérico qué cargar). El código de artículos original es fácil de seguir.

Cuestiones relacionadas