Reflection.Net: ¿cómo cargar dependencias?
-
05-07-2019 - |
Pregunta
Intento agregar un sistema de complementos a mi aplicación Windows.Net usando Reflection; pero falla cuando hay addon con dependencie.
La clase de complemento tiene que implementar una interfaz 'IAddon' y tener un constructor vacío.
El programa principal carga el complemento utilizando Reflection:
Assembly assembly = Assembly.LoadFile(@"C:\Temp\TestAddon\Addon.dll");
Type t = assembly.GetType("Test.MyAddon");
ConstructorInfo ctor = t.GetConstructor(new Type[] { });
IAddon addon= (IAddon) ctor.Invoke(new object[] { });
addon.StartAddon();
Funciona muy bien cuando el complemento no usa dependencie.
Pero si mi referencia de complemento y usa otra DLL (C: \ Temp \ TestAddon \ MyTools.dll) que se guarda cerca del complemento en el disco, falla:
System.IO.FileNotFoundException: no se pudo cargar el archivo o el ensamblaje 'MyTools.dll' o una de sus dependencias.
No quiero copiar el archivo DLL de complementos cerca de mi ejecutable, ¿cómo puedo hacer para decirle al tiempo de ejecución de .Net que busque en " C: \ Temp \ TestAddon \ " para cualquier dependencia?
Tenga en cuenta que agregar
Assembly assembly = Assembly.LoadFile(@"C:\Temp\TestAddon\MyTools.dll");
no cambies nada.
Solución
Si MyTools.dll se encuentra en el mismo directorio que Addon.dll , todo lo que debe hacer es llamar a Assembly.LoadFrom
en su lugar de Assembly.LoadFile
para hacer que su código funcione. De lo contrario, manejar el evento AppDomain.AssemblyResolve
es el camino a seguir.
Otros consejos
¿Ha estudiado el uso de un contenedor Inversion Of Control ? Uso Castle Windsor con un archivo Boo externo que me permite extender fácilmente la aplicación sin tener que volver a compilar o preocuparme por el suministro de dependencias
Puede utilizar la reflexión para acceder al Assembly.
_GetReferencedAssemblies()
privado.
Aunque, el método podría cambiar en una versión futura de .NET framework, no parece probable. ASP.NET depende en gran medida de ello, aunque es posible que lo puedan mover de < code> mscorlib to System.Web
que es el único conjunto que conozco desde donde se hace referencia al método.
Assembly.LoadFrom funciona bien hasta que trato de usar un servicio web en mi complemento, tuve un " No se puede convertir un objeto de tipo "X" para escribir "X" " excepción.
Es feo, pero usaré Assembly.LoadFile con AppDomain.AssemblyResolve.
Gracias chicos.
Par de opciones:
- Puede adjuntar a
AppDomain.AssemblyResolve
para ayudar al CLR a resolver el ensamblaje. - Podría considerar la posibilidad de aislar complementos en su propio espacio de nombre
AppDomain
(consulteSystem.AddIn
y este sitio web ).