我目前正在尝试学习如何使用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方法有关,但我不确定。
非常感谢任何帮助!
感谢。
答案 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)));
这很有效。我不知道它是否违反任何规则或原则,但它现在有效。