Как в Prism вставить интерфейс в конструктор модуля вместо типа?

В моем приложении призмы я получаю сообщение об ошибке Ошибка активации произошла при попытке получить экземпляр типа CustomerModule, ключ \ "\".

Это вызвано тем, что в мой модуль клиентов я пытаюсь внедрить "menuManager" типа IMenuManager:

namespace CustomerModule
{
    public class CustomerModule : IModule
    {
        private readonly IRegionManager regionManager;
        private readonly IUnityContainer container;
        private readonly IMenuManager menuManager;

        public CustomerModule(IUnityContainer container, 
            IRegionManager regionManager, 
            IMenuManager menuManager)
        {
            this.container = container;
            this.regionManager = regionManager;
            this.menuManager = menuManager;
        }

        public void Initialize()
        {

            container.RegisterType<IMenuManager, MenuManager>(new ContainerControlledLifetimeManager());
        ...

Однако, если я изменю конструктор CustomerModule, чтобы ввести тип вместо интерфейса, тогда он будет работать:

public CustomerModule(IUnityContainer container, 
    IRegionManager regionManager, 
    MenuManager menuManager)

Итак, где мне нужно зарегистрировать мой MenuManager как реализующий IMenuManager? Похоже, что зарегистрировать его в методе Initialize CustomerModule уже слишком поздно.

ОТВЕЧАТЬ:

Я поместил его в ConfigureContainer (), и он работал нормально, обязательно оставьте в "base.ConfigureContainer ()":

protected override void ConfigureContainer()
{
    base.ConfigureContainer();
    Container.RegisterType<MenuManager>(new ContainerControlledLifetimeManager());
}

person Edward Tanguay    schedule 21.07.2009    source источник
comment
Я все еще подумываю об изменении того, как это работает. У ваших модулей по-прежнему должна быть конкретная ссылка на ваш тип MenuManager. Я настоятельно рекомендую вам следовать шаблону, который я изложил для вас в примере, который я разместил здесь: stackoverflow.com/questions/1152282/   -  person Anderson Imes    schedule 22.07.2009


Ответы (2)


Зачем вам нужен MenuManager в том же модуле, в котором вы его регистрируете?

Если вы действительно не думаете, что ваш MenuManager должен предоставляться внешним модулем, вы можете подумать о том, чтобы поместить эту регистрацию в свой загрузчик, если ваши модули будут зависеть от него. Это было бы что-то, что вы бы поместили в свой метод ConfigureContainer вашего загрузчика.

person Anderson Imes    schedule 21.07.2009
comment
Я заставил его работать в GetModuleCatalog (), но не знал о ConfigureContainer, теперь я положил его туда, спасибо. - person Edward Tanguay; 22.07.2009

Как вы, наверное, поняли, это потому, что конструктор вызывается перед методом инициализации.

Два решения:

1) Имейте в своем проекте Shell класс ShellBootstrapper с методом, который вызывается при загрузке программы.

Попросите метод в загрузчике зарегистрировать любые глобальные интерфейсы в вашем контейнере.

2) В качестве альтернативы выньте IMenuManager из конструктора и просто разрешите его после того, как вы его зарегистрируете.

public void Initialize()
{
    container.RegisterType<IMenuManager, MenuManager>(new ContainerControlledLifetimeManager());
    this.menuManager = container.Resolve<IMenuManager>();
}

Надеюсь это поможет!

person Andy Clarke    schedule 21.07.2009