具有多个参数的Unity / Caliburn Micro,Injection Constructor

时间:2011-07-04 10:16:26

标签: mvvm unity-container caliburn.micro constructor-injection

我目前正在尝试学习如何使用Unity和Caliburn Micro实现MVVM。在其他地方寻求帮助后,我仍然不确定如何正确设置构造函数注入。由于我缺乏MVVM或其他方面的专业知识,我不知道这是否有效。

我的问题是我想将两个IScreen对象传递到我的主窗口(shell)类,可以在用户单击按钮之间导航。以下是我的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实例。我不知道如何指定我希望它在CampaignViewModel和StringsViewModel的一个实例中传递的InjectionConstructor。我觉得它可能与GetInstance方法有关,但我不确定。

非常感谢任何帮助!

感谢。

2 个答案:

答案 0 :(得分:1)

在构造函数中,两次定义相同的接口。

DI框架将如何知道哪个是哪个?答:它不能。

  

所以不要使用2个接口:

 public MainWindowViewModel(ICampaignScreen campaignViewModel, IStringsScreen stringsViewModel)

您可以从IScreen继承这两个:

 public interface ICampaignScreen : IScreen

既不需要向IScreen添加任何内容 - 它们只是为框架提供了区分它们的方法。

答案 1 :(得分:1)

更改:

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

要:

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

这很有效。我不知道它是否违反任何规则或原则,但它现在有效。