2012-04-15 54 views
8

Mi aplicación carga todos los ensamblados de biblioteca ubicados en su ruta de ejecución y ejecuta métodos preconfigurados contra clases contenidas.Cargar un conjunto en tiempo de ejecución que haga referencia al conjunto de llamadas

Ahora necesito hacer lo mismo con un conjunto que hace referencia a mi conjunto de aplicaciones. ¿Es esto posible y hay implicaciones negativas de las que deba tener conocimiento?

Asamblea Maestro:

public abstract class TaskBase 
{ 
    public abstract void DoWork(); 
} 

LoadAssemblyFromFile("Assembly0001.dll"); 
Assembly0001.Task1.DoWork(); 

Asambleas Niños:

public sealed class Task1: MasterAssembly.TaskBase 
{ 
    public override void DoWork { /* whatever */ } 
} 
+0

Hago esto todo el tiempo sin ningún problema. El único problema con el que me he encontrado (algunas veces, en realidad) es la gestión de versiones del ensamblado _master_. Si realiza cambios en _master_ sin recompilar a los niños, puede encontrarse con algunos problemas extraños. –

+0

@ M.Babcock: Gracias. Por curiosidad, ¿qué tipo de problemas? No vuelvo a autoincrementar las versiones de ensamblado al volver a compilar. Estoy suponiendo que DEBERÍA eludir cualquier problema que pueda haber encontrado. ¿Tus pensamientos? –

+0

El problema más común que he encontrado es que una definición de método cambia rompiendo la compatibilidad con versiones anteriores, aunque en otros casos he experimentado la temida "_Type_ está definida en ambas excepciones _Master_ y _Master_" (de la memoria no es texto literal, pero está cerrado lo suficiente como para que lo reconozcas). –

Respuesta

6

Sí, esto es posible. Siempre que su ensamblaje maestro no haga referencia a los ensamblajes secundarios, debería estar bien. De lo contrario, tendrás una dependencia circular.

El ensamblaje maestro simplemente cargará los ensamblajes secundarios y no sabrá nada sobre ellos, excepto que implementan una interfaz. De esta forma, el ensamblaje maestro no necesita hacer referencia a los ensamblajes secundarios.

Ningún truco, hasta donde yo sé. Utilizamos esta técnica con éxito para ciertos escenarios.

+0

Gracias. Fuera de contexto, ¿hay alguna manera de cargar ensamblajes desde la memoria sin que el archivo de ensamblaje esté presente en el disco? Estas versiones periódicas de la reunión están presentes en una base de datos central y preferiría que sea razonablemente difícil para los usuarios tenerlas en sus manos. Por supuesto, entiendo que no hay una forma infalible de lograr esto. –

+0

Sí, teníamos aplicaciones para móviles como esa. El binario ensamblado se almacenó en la base de datos, se recuperó y se cargó de esa manera. Podrías hacer lo mismo. –

+0

Lo encontró: Assembly.Load (byte []). –

1

En mi experiencia no hay nada de malo en esto. De hecho, MEF usa esta técnica en la forma de AssemblyCatalog (donde sus implementaciones están EN EL ensamblaje maestro) y DirectoryCatalog (donde las implementaciones de una interfaz se realizan en ensamblajes en un directorio específico).

Ambos se pueden usar juntos en un AggregateCatalog sin problemas.

0

El único "problema" es que no se puede escribir Assembly0001.Task1 en su conjunto maestra pero se puede encontrar la tarea correcta en el montaje cargado e invocar que uno:

var asm = LoadAssemblyFromFile("Assembly0001.dll"); 
var taskType = asm.GetTypes().FirstOrDefault(t => typeof(TaskBase).IsAssignableFrom(t)); 
var task = (TaskBase)Activator.CreateInstance(taskType); 
task.DoWork(); 

usted todavía necesita agregar algunas verificaciones de seguridad adicionales :)

+0

Sí, por supuesto. Crear una instancia de tiempo de ejecución por tipo es la única forma de lograr esto. ¿Qué tipo de controles de seguridad recomendarías? La aplicación necesita asegurarse de que está ejecutando nuestro propio código (posiblemente a través de un hash unidireccional). ¿Qué más? –

+0

Bueno, en su mayoría solo verificaciones nulas, si realmente desea crear un recinto para ejecutar sus tareas puede ser un poco más difícil. – XIU

0

No ha publicado el código de su método LoadAssemblyFromFile ("..."), pero si usa Assembly.LoadFrom() o Assembly.LoadFile() para cargar ensamblajes, podría obtener InvalidCastException, MissingMethodException u otras excepciones, especialmente si su aplicación y el ensamblaje cargado hacen referencia a otro ensamblaje idéntico. LoadFrom() y LoadFile() cargan ensamblajes en contextos de vinculación diferentes a los de su aplicación. Consulte this para obtener una explicación detallada.

Cuestiones relacionadas