Pregunta

Tengo esta aplicación usando CAL. Todos los módulos derivan de una clase especial, ModuleBase , que tiene un método abstracto, digamos ApplySecurity implementado en cada uno de ellos.

OK. Cargo los módulos en el programa de arranque, y después de llamar a bootstrapper.Run () , quiero acceder a todos los módulos que se cargaron y llamar a este ApplySecurity método.

Intenté esto:

IModuleCatalog moduleCatalog = this.Container.Resolve<IModuleCatalog>();

moduleCatalog.Modules.ToList().ForEach(m => 
{
    (this.Container.Resolve(Type.GetType(m.ModuleType, false, false)) 
         as ModuleBase).ApplySecurity(); //^^^ this is making new instances!!
});

pero esto está haciendo nuevas instancias de módulos, y quiero hacer referencia a los que ya se inicializaron.

Espero haber sido lo suficientemente claro,

Teodor.

¿Fue útil?

Solución

Parece que el problema es que cuando el Módulo está registrado en el contenedor, no está registrado como una instancia específica, por lo que cuando solicita la resolución, se crea una nueva instancia. He echado un vistazo al código fuente de CAL y el registro se realiza en medio de un conjunto complicado de llamadas a métodos, por lo que dudo que pueda proporcionar su propia implementación de manera sensata.

Esto significa que necesitará registrar la instancia de su módulo en otro lugar. La manera de hacer esto fuera de mi cabeza es crear algún tipo de catálogo de instancia de módulo y agregar una llamada a cada uno de los métodos de inicialización del módulo para registrarse con él.

public class ModuleInstanceCatalog : IModuleInstanceCatalog
{
     private Dictionary<Type, ModuleBase> _modules = new Dictionary<Type, ModuleBase>();

     public void RegisterModuleInstance(ModuleBase module)
     {
         _modules.Add(module.GetType(), module);
     }

     public ModuleBase GetModuleInstanceByType(Type type)
     {
         return _modules[type];
     }
}

En su Bootstrapper CreateShell ():

this.Container.RegisterInstance<IModuleInstanceCatalog>(new ModuleInstanceCatalog());

En cada módulo Initilize ():

IModuleInstanceCatalog catalog = this.Container.Resolve<IModuleInstanceCatalog>();
catalog.RegisterModuleInstance(this);

Luego reemplace el código en su pregunta con:

IModuleCatalog moduleCatalog = this.Container.Resolve<IModuleCatalog>();
IModuleInstanceCatalog instanceCatalog = this.Container.Resolve<IModuleInstanceCatalog>();

moduleCatalog.Modules.ToList().ForEach(m => 
{
    instanceCatalog.GetModuleInstanceByType(m.ModuleType).ApplySecurity();
});

No estoy demasiado contento con esto, ya que parece un poco falso, pero debería funcionar para lo que quieres.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top