0

我有这个使用 CAL 的应用程序。所有的模块都派生自一个特殊的类,ModuleBase它有一个抽象方法,比如说ApplySecurity在每个模块中实现。

好的,我在引导程序中加载模块,在我调用之后bootstrapper.Run(),我想访问所有加载的模块并调用这个ApplySecurity方法。

我试过这个:

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!!
});

但这正在制作模块的新实例,我想引用已经初始化的那些。

我希望我已经足够清楚了,

特奥多尔。

4

1 回答 1

0

看起来问题在于,当模块注册到容器时,它没有注册为特定实例,因此当您请求解析时,会创建一个新实例。我查看了 CAL 源代码,注册发生在一组复杂的方法调用的中间,所以我怀疑你是否能够明智地提供自己的实现。

这意味着您需要在其他地方注册模块的实例。我想到的方法是创建某种模块实例目录并添加对每个模块的 initilize 方法的调用以向它注册。

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];
     }
}

在您的引导程序 CreateShell() 中:

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

在每个模块的 Initilize() 中:

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

然后将问题中的代码替换为:

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

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

我对此并不太满意,因为它感觉有点像软糖,但它应该可以满足您的需求。

于 2009-06-19T12:45:24.593 回答