在CAL中,如何获取模块实例的引用?

时间:2009-06-19 11:32:40

标签: c# unity-container cal

我有使用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!!
});

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

我希望我已经足够清楚,

特奥多尔。

1 个答案:

答案 0 :(得分: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];
     }
}

在你的Bootstrapper 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();
});

我对此并不十分满意,因为它感觉有点像软糖,但它应该适用于你想要的东西。