Unity/Caliburn Micro, Injection Constructor with multiple parameters

China☆狼群 提交于 2019-12-10 11:57:27

问题


I am currently trying to learn how to implement MVVM using Unity and Caliburn Micro. After looking around for help elsewhere I am still unsure about how to set up the Constructor Injection properly. I don't know if this is not working due to my lack of expertise in MVVM or something else.

My problem is I want to pass in two IScreen Objects into my main window(shell) Class that can be navigated between when the user clicks on a button. Here is the code for the constructor in my MainWindowViewModel class:

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

This is the code I am using in my Bootstrapper(Unity) class:

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

When this runs the MainWindowViewModel receives two instances of StringsViewModel. Although if I were to put a key into the statement:

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

Then it passes in two instances of CampaignsViewModel. I don't know how to specify to the InjectionConstructor that I want it to pass in one instance of CampaignViewModel and StringsViewModel. I have a feeling it may have something to do with the GetInstance method, but I am unsure.

Any help would be greatly appreciated!

Thanks.


回答1:


In your constructor you define the same interface twice.

How will the DI framework know which is which?? Answer: it can't.

So instead of this use 2 interfaces:

 public MainWindowViewModel(ICampaignScreen campaignViewModel, IStringsScreen stringsViewModel)

You can make both of these inherit from IScreen:

 public interface ICampaignScreen : IScreen

and neither need add anything to IScreen - they simply provide a means for the Framework to differentiate between them.




回答2:


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.



来源:https://stackoverflow.com/questions/6570109/unity-caliburn-micro-injection-constructor-with-multiple-parameters

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!