Search code examples
xamlprismunity-containerconstructor-injection

Declaring ViewModel using Constructor Injection in XAML


I'm trying out Unity and I'm having problems declaring my viewmodel in XAML. Can you help me out? XAML:

<UserControl.DataContext>
    <search:SearchBoxViewModel />
</UserControl.DataContext>

Constructor:

   [ImportingConstructor]
    public SearchBoxViewModel(IRegionManager regionManager, IEventAggregator eventAggregator)
    {
        this.regionManager = regionManager;
        this.eventAggregator = eventAggregator;
    }

When I try to execute I get a resolutionfailedexception. This worked when the viewmodel had an empty constructor. It seems as if it's having problems with the constructor injection.

If I load the module like this:

var searchView = Container.Resolve<SearchBoxView>();
        searchView.DataContext = Container.Resolve<SearchBoxViewModel>();
        //RegionManager.RegisterViewWithRegion(RegionNames.SearchRegion, typeof(SearchBoxView));
        RegionManager.Regions[RegionNames.SearchRegion].Add(searchView);

It works.

Is there any possibility to do this with xaml ( with I personally think is better )?

By the way: I'm creating an application with wpf that primarily communicates with a webservice. What should I rather user: unity or MEF and what are the big differences between the two?

Thanks, Raphi


Solution

  • http://msdn.microsoft.com/en-us/library/ms753379.aspx:

    Requirements for a Custom Class as a XAML Element

    In order to be able to be instantiated as an object element, your class must meet the following requirements:

    • Your custom class must be public and support a default (parameterless) public constructor. (See following section for notes regarding structures.)

    • ...

    So, if you want to use dependencies, you should right something like:

    var searchView = Container.Resolve<SearchBoxView>();
    
    public class SearchBoxView: UserControl
    {
      [Dependency]
      public SearchBoxViewModel ViewModel
      {
        get { return (SearchBoxViewModel)DataContext; }
        set { DataContext = value; }
    }