我有使用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!!
});
但这是模块的新实例,我想引用那些已经初始化的模块。
我希望我已经足够清楚,
特奥多尔。
答案 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();
});
我对此并不十分满意,因为它感觉有点像软糖,但它应该适用于你想要的东西。