Unity/Caliburn Micro, конструктор инъекций с несколькими параметрами

В настоящее время я пытаюсь узнать, как реализовать MVVM с помощью Unity и Caliburn Micro. После поиска помощи в другом месте я все еще не уверен, как правильно настроить внедрение конструктора. Я не знаю, не работает ли это из-за отсутствия у меня опыта в MVVM или чего-то еще.

Моя проблема в том, что я хочу передать два объекта IScreen в мой класс главного окна (оболочки), между которыми можно перемещаться, когда пользователь нажимает кнопку. Вот код конструктора в моем классе MainWindowViewModel:

private IScreen campaignViewModel, stringsViewModel;
public MainWindowViewModel(IScreen campaignViewModel, IScreen stringsViewModel)
{
    this.campaignViewModel = campaignViewModel;
    this.stringsViewModel = stringsViewModel;
    ActiveItem = this.campaignViewModel;
}

Это код, который я использую в своем классе Bootstrapper (Unity):

    private static IUnityContainer BuildContainer()
    {
        IUnityContainer result = new UnityContainer();
        result
            .RegisterInstance(result)
            .RegisterInstance<IWindowManager>(new WindowManager())
            .RegisterInstance<IEventAggregator>(new EventAggregator());

        result
            .RegisterType<IScreen, CampaignsViewModel>()
            .RegisterType<IScreen, StringsViewModel>()
            .RegisterType<MainWindowViewModel>(new InjectionConstructor(typeof(IScreen), typeof(IScreen)));

        return result;
    }

    protected override object GetInstance(Type service, string key)
    {
        var result = unity.Resolve(service, key);

        if (result == null)
            throw new Exception(string.Format("Could not locate any instance of contract {0}", service));
        return result;
    }

При этом MainWindowViewModel получает два экземпляра StringsViewModel. Хотя, если бы я поместил ключ в утверждение:

result.RegisterType<IScreen, StringsViewModel>("StringsView");

Затем он проходит через два экземпляра CampaignsViewModel. Я не знаю, как указать InjectionConstructor, что я хочу, чтобы он проходил в одном экземпляре CampaignViewModel и StringsViewModel. У меня есть ощущение, что это может иметь какое-то отношение к методу GetInstance, но я не уверен.

Любая помощь будет принята с благодарностью!

Спасибо.


person stuartmclark    schedule 04.07.2011    source источник


Ответы (2)


В вашем конструкторе вы дважды определяете один и тот же интерфейс.

Как структура DI узнает, что есть что? Ответ: не может.

Поэтому вместо этого используйте 2 интерфейса:

 public MainWindowViewModel(ICampaignScreen campaignViewModel, IStringsScreen stringsViewModel)

Вы можете сделать так, чтобы оба они наследуются от IScreen:

 public interface ICampaignScreen : IScreen

и им не нужно ничего добавлять в IScreen — они просто предоставляют фреймворку возможность различать их.

person BonyT    schedule 04.07.2011
comment
Что ж, я просто изменил инъекцию на: new InjectionConstructor(typeof(CampaignsViewModel),typeof(StringsViewModel)) и сделал это. Я попробовал ваш метод создания интерфейсов для каждой из моделей представления, но не смог его скомпилировать. Все равно спасибо. - person stuartmclark; 04.07.2011
comment
Оглядываясь назад на ваш ответ, я понимаю, что вы были фактически правы, и хотя то, что я сделал, сработало, это был скорее взлом, чем фактическое получение единства для разрешения интерфейса. Создание интерфейса, производного от IScreen, для каждой из моделей View было правильным шагом. Спасибо. - person stuartmclark; 09.06.2012

Измененный:

 result
            .RegisterType<IScreen, CampaignsViewModel>()
            .RegisterType<IScreen, StringsViewModel>()
            .RegisterType<MainWindowViewModel>(new InjectionConstructor(typeof(IScreen), typeof(IScreen)));

To:

 result
            .RegisterType<IScreen, CampaignsViewModel>()
            .RegisterType<IScreen, StringsViewModel>()
            .RegisterType<MainWindowViewModel>(new InjectionConstructor(typeof(CampaignsViewModel), typeof(StringsViewModel)));

И это сработало. Не знаю, нарушает ли это какие-то правила или принципы, но пока работает.

person stuartmclark    schedule 04.07.2011