0

我目前正在尝试学习如何使用 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 实例。我不知道如何向 InjectionConstructor 指定我希望它在 CampaignViewModel 和 StringsViewModel 的一个实例中传递。我感觉它可能与 GetInstance 方法有关,但我不确定。

任何帮助将不胜感激!

谢谢。

4

2 回答 2

1

Changed:

 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)));

And this worked. I don't know if it violates any rules or principles but it works for now.

于 2011-07-04T10:42:10.170 回答
1

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

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

所以代替这个使用2个接口:

 public MainWindowViewModel(ICampaignScreen campaignViewModel, IStringsScreen stringsViewModel)

您可以使这两个都从 IScreen 继承:

 public interface ICampaignScreen : IScreen

也不需要向 IScreen 添加任何东西——它们只是为框架提供了一种区分它们的方法。

于 2011-07-04T10:23:49.503 回答