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

发布于 2024-07-24 22:34:59 字数 631 浏览 6 评论 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!!
});

但这正在创建模块的新实例,并且我想引用已经初始化的实例。

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

特奥多。

I have this application using CAL.
All the modules derive from a special class, ModuleBase, which has an abstract method, say ApplySecurity implemented in each one of them.

OK I load the modules in the bootstrapper, and after i call bootstrapper.Run(), i want to access all the modules that were loaded and call this ApplySecurity method.

I tried this:

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

but this is making new instances of modules, and i want to reference the ones that were already initialized.

I hope i have been clear enough,

Teodor.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风为裳 2024-07-31 22:34:59

看起来问题在于,当模块注册到容器时,它没有注册为特定实例,因此当您请求解析时,会创建一个新实例。 我查看了 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();
});

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

It looks like the problem is that when the Module is registered to the container it isn't registered as a specific instance, so when you request the resolve a new instance is created. I've had a look through the CAL source code and the registering happens in the middle of a convoluted set of method calls, so I doubt you'll be able to sensibly supply your own implementation.

This means you'll need to register the instance of your module somewhere else. The way to do this off the top of my head is to create some kind of module instance catalog and add a call to each of the module's initilize method to register with it.

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

In your Bootstrapper CreateShell():

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

In each module's Initilize():

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

Then replace the code in your question with:

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

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

I'm not overly happy with this as it feels like a bit of a fudge, but it should work for what you want.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文