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.

¿Fue útil?

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:

  1. Puede adjuntar a AppDomain.AssemblyResolve para ayudar al CLR a resolver el ensamblaje.
  2. Podría considerar la posibilidad de aislar complementos en su propio espacio de nombre AppDomain (consulte System.AddIn y este sitio web ).
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top