Unity Dependency Injection from usercontrol viewmo

2019-09-12 19:27发布

问题:

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:

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()
   }
}

回答1:

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