В CAL, как я могу получить ссылку на экземпляр модуля? - PullRequest
0 голосов
/ 19 июня 2009

У меня есть это приложение, использующее 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!!
});

но это создает новые экземпляры модулей, и я хочу сослаться на те, которые уже были инициализированы.

Надеюсь, я достаточно ясно,

Teodor.

1 Ответ

0 голосов
/ 19 июня 2009

Похоже, проблема в том, что когда модуль зарегистрирован в контейнере, он не регистрируется как конкретный экземпляр, поэтому при запросе разрешения создается новый экземпляр. Я просмотрел исходный код 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();
});

Я не слишком доволен этим, так как это похоже на выдумку, но это должно работать для того, что вы хотите.

...