Ryan Amies
Ryan Amies

Reputation: 4932

Dependency Injection with MVVM and Child Windows

I am using MVVM Light and I'm currently using SimpleIoC that comes with the package. I'm getting a bit stuck with the dependency injection. I have a bunch of services that I want to use in my view models, however most windows are a List-Edit paradigm, i.e. one screen lists all of type Person and then you can Add or Edit a Person via a new screen.

When I was doing all code in the code behind my code for adding and editing a record was as follows:

View

private void btnEdit_Click(object sender, RoutedEventArgs e)
{
    _viewModel.Edit();
}

private void btnAdd_Click(object sender, RoutedEventArgs e)
{
    _viewModel.Add();
}

View Model

public void Add()
{
    var f = new TypeDetails();
    f.Show();
}
public void Edit()
{
   if (SelectedItem == null)
      return;
   var f = new TypeDetails(SelectedItem.Id);
   f.Show();
}

The constructor of TypeDetails is as follows:

public TypeDetails(int id = 0)
{
    InitializeComponent();
    _viewModel = new TypeDetailsViewModel(id);
    DataContext = _viewModel;
}

What would the best be to implement this type functionality with MVVM Light? I have been using the ViewModelLocator class for the List screens, however I cannot see a way to do this using the SimpleIoC. My way round so far has been to keep the constructor the same, which works fine until I need to inject dependencies into the TypeDetailsViewModel such as a service. With a service the constructor of TypeDetailsViewModel would be:

public TypeDetailsViewModel(ISomeService someService, int id = 0)
{
     ...
}

But that means in my view constructor I have to build these dependencies one at a time and manually inject them...

public TypeDetails(int id = 0)
{
    InitializeComponent();
    _viewModel = new TypeDetailsViewModel(SimpleIoC.Current.GetInstance<ISomeService>(),id);
    DataContext = _viewModel;
}

Is there a better way to do this?

Upvotes: 2

Views: 1914

Answers (1)

vidalsasoon
vidalsasoon

Reputation: 4401

  • First off I would look into the "RelayCommand" class which is part of MVVM Light. It will remove the need for events in your code behind. Start with that.

  • You should always favor "Constructor Injection" instead of the ServiceLocator (ex: SimpleIoC.Current.GetInstance())

  • Your ViewModel constructor should only be injecting services and not primitive types like "int". In your example "int id" should be the parameter of a method and not injected.

Ex: Instead, your TypeDetailsViewModel should look more like:

public TypeDetailsViewModel(ISomeService someService)
{
     TypeDetail GetDetailsCommand(int id)
     {
        ...
     }
}

Upvotes: 5

Related Questions