0

I have a UserControl which is bound to a viewmodel. The viewmodel has parameters in the constructor which is done via dependency injection. The dependency injection is working fine up to this point.

And then I have a CustomUserControl which is Used in my UserControl1View. How do I get the Dependency injection working in my CustomUserControl?

I am new to dependency injection and did some research, but can't seem to get it working. I get an error on

public partial class UserControl1View : UserControl, IView {
    public UserControl1View( ) {
        InitializeComponent( );
    }
}  

This is the error: enter image description here

Here is the example of the code.

UserControl:

public partial class UserControl1View : UserControl, IView {
    public UserControl1View( ) {
        InitializeComponent( );
    }
}

UserControlViewModel:

public class UserControl1ViewModel 
{
    private readonly ISomeDataService dataService;
    public UserControl1ViewModel (ISomeDataService dataservice, IUnityContainer container ) 
    {
       //Please note that the Dependency injection still works in this class, to much to explain the whole structure.   
       this.dataService = dataservice;
       container.RegisterType( typeof( IView ), typeof( CustomUserControlView ) ); 
       var view = container.Resolve<CustomUserControlView>( );
    }

XAML:

<uc:CustomUserControlView/>

CustomUserControl:

public partial class CustomUserControlView : UserControl, IView 
{
    public CustomUserControlView(IUnityContainer container) 
    {
        container.RegisterType( typeof( IViewModel ), typeof( CustomControlViewModel ) );
        var viewModel = container.Resolve<CustomControlViewModel>( );
        this.DataContext = viewModel;
        InitializeComponent( );
    }
}

CustomUserControlViewModel:

public partial class CustomUserControlViewModel : UserControl, IView 
{
   private readonly ISomeDataService dataService;
   public CustomUserControlViewModel(ISomeDataService dataservice) 
   {
      var data = dataService.GetsomeCollection()
   }
}
StepUp
  • 36,391
  • 15
  • 88
  • 148
user1702369
  • 1,089
  • 2
  • 13
  • 31

1 Answers1

4

Solution is simple. Don't use DI/IoC container to inject controls. It's not going to work and was never supposed to work.

User controls (in contrast to views) are meant to be self-contained and work out of the box with other applications or the IDE designer w/o requiring a container. Otherwise they just won't work well with the designer, as the Xaml designer has no concept of DI/IoC and won't know how to resolve/instantiate a certain class and requires an parameterless constructor. Also a "user control" doesn't split it's logic into a ViewModel.

A view on other side is just an UI template without code. It also derives from Windows or UserControl class, but has no logic of it's own and is not reusable. A view is always very specific for a special ViewModel and ViewModels are very specific to one application. For views one can use DI, but only to inject the ViewModel (i.e. depending if you are going for View-first or ViewModel-first approach).

On a side note, your UserControl1ViewModel violates MVVM as your VM has references to your View, which beats the whole purpose of MVVM

Tseng
  • 61,549
  • 15
  • 193
  • 205
  • Hi thanks for your answer, it helps more than you could think. I am hust wondering the following. Isn't a view or usercontrol the same thing in principle if it comes to WPF? To put it simple, all our WPF windows/views are usercontrols in this specific project. And I have a folder called shared where all the usercontrols that is shared in the project resides. So my usercontrol dont need to be used outside the project, therefore I want to link it to a viewmodel where the viewmodel is injected. – user1702369 May 13 '16 at 12:24
  • Technically yes, but as I said: View has no logic, so no code behind. A CalendarControl (user control) must draw the calender, handle clicks etc. that is part of code-behind and it exposes DependencyProperties where application specific viewmodels can bind to. In a pure view, there is no need for DPs – Tseng May 13 '16 at 12:54