2009-01-19 17 views
5

Planteamiento del problema: Implemente un sistema de complemento que permita sobrescribir los ensamblajes asociados (evite el bloqueo de archivos). En .Net, los ensamblados específicos no se pueden descargar, solo se pueden descargar AppDomains completos.¿Cómo implemento los plugins de .NET sin usar AppDomains?

Lo publico porque cuando intentaba resolver el problema, cada solución hacía referencia al uso de múltiples AppDomains. Varios AppDomains son muy difíciles de implementar correctamente, incluso cuando se diseñaron al inicio de un proyecto.

Además, AppDomains no funcionó para mí porque necesitaba transferir el tipo entre dominios como una configuración para la actividad de InvokeWorkflow de Speech Server worfklow. Desafortunadamente, al enviar un tipo de dominio, el ensamblado se inyecta en el dominio de aplicación local.

Además, esto es relevante para IIS. IIS tiene una configuración de Shadow Copy que permite sobrescribir un ensamblaje en ejecución mientras se carga en la memoria. El problema es que (al menos en XP, no se probó en servidores de producción 2003) cuando se carga un ensamblado mediante programación, la instantánea no funciona (porque está cargando el archivo DLL, no IIS).

Respuesta

8
  1. Compruebe si el conjunto ya está cargado (para evitar pérdidas de memoria causadas al cargar el mismo conjunto una y otra vez).
  2. Si no está cargado, lea el conjunto en una matriz de bytes. Esto evitará que se bloquee el archivo.
  3. de alimentación del conjunto de bytes como un argumento a Assembly.Load

El código siguiente se supone que conoce el NombreCompleto de un montaje.

Assembly assembly = null; 

foreach(Assembly loadedAssembly in AppDomain.CurrentDomain.GetAssemblies()) 
    if (loadedAssembly.FullName == "foobar, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null") 
     assembly = loadedAssembly; 

if(assembly == null) 
{ 
    byte[] studybin = System.IO.File.ReadAllBytes(@"C:\pathToAssembly\foobar.dll"); 
    assembly = Assembly.Load(studybin);     
} 

Tenga en cuenta que si usted está tratando de encontrar un ensamblaje específico en un directorio, puede ejecutar 'System.Reflection.AssemblyName.GetAssemblyName (ruta);' para ver si el nombre completo coincide con lo que estás buscando. 'GetAssemblyName (ruta)' NO inyecta el ensamblado en su AppDomain actual.

También tenga en cuenta que esta solución no es apropiada para aplicaciones que raramente deben reiniciarse Y los conjuntos cambian con alta frecuencia. Cada vez que se carga un ensamblaje, la huella de memoria de su aplicación crecerá. No hay un método para descargar un ensamblaje, por lo tanto, la única opción para reducir el uso de memoria es reiniciar la aplicación. Sin embargo, esta limitación a menudo es preferible a la gran sobrecarga de rendimiento, memoria y complejidad del código al usar múltiples dominios de aplicaciones. Esta limitación también es inevitable si desea trabajar con Type s.

+0

Supongo que esto significa que todavía tendría que reiniciar la aplicación para utilizar el nuevo tapón en una vez que había sido sustituido en el disco? Tenía la impresión de que una vez que se ha cargado un tipo, no se puede cambiar, incluso si vuelve a cargar el conjunto. –

+3

Puede usar el nuevo tipo simultáneamente. No estás técnicamente "recargando" el conjunto. En su lugar, está cargando el nuevo ensamblaje al lado del anterior. Si los ensambles cambian con frecuencia, eventualmente se quedará sin memoria y necesitará reiniciar la aplicación. –

2

Si desea aislar sus complementos, usted debe ...

  1. crear un tipo que se extiende MarshallByRefObject que interactuar con sus complementos (deja llamada que FOOMASTER)
  2. Crear un nuevo appdomain (vamos a llamarlo addinLand)
  3. Llamada addinLand.CreateInstanceAndUnwrap a crear una instancia de FOOMASTER en addinLand y obtener un proxy en el dominio aplicación actual
  4. Dile FOOMASTER para cargar sus complementos

Ahora sus complementos son cargados en addinLand y se puede interactuar con ellos desde su dominio principal a través de su proxy FOOMASTER. Cuando tus complementos fallan, no eliminan tu aplicación.

Es un proceso interesante y ligeramente confuso. Originalmente pensé que la idea era cargar tus complementos y luego incorporarlos al dominio de la aplicación actual como proxies transparentes, pero el mejor diseño es dejar los complementos como objetos simples que interactúan con los tipos más complejos que creas (FOOMASTER), que se extienden MarshallByRefObject, que se cargan en el dominio de la aplicación addinLand y cuyos proxies transparentes interactúan.

Los capítulos 21 y 22 de CLR Via C# son muy útiles para comprender el proceso.

2

Si está interesado en un método serio para construir un sistema con una arquitectura de complemento, es posible que desee comprobar MAF (Framework de Complemento Administrado), que ahora es parte de .NET Framework, es decir, el Sistema. Espacio de nombres AddIn.

Le ayudará a gestionar el aislamiento de complementos y el control de versiones, incluso la compatibilidad con contratos anteriores.

Aquí hay un poco de curva de aprendizaje, por lo que puede que no sea exactamente lo que estás buscando.

http://msdn.microsoft.com/en-us/library/bb384200.aspx

Cuestiones relacionadas