2

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?

Ryan Amies
  • 4,902
  • 1
  • 21
  • 36

1 Answers1

5
  • 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)
     {
        ...
     }
}
Community
  • 1
  • 1
vidalsasoon
  • 4,365
  • 1
  • 32
  • 40
  • I have been using RelayCommand, which has eliminated those events, I only had them for examples on how the code used to be. I am curious about where the DataContext is set for the Details screen, should the Ctor of the View call `SimpleIoC` and `GetInstance()`? With regards to the injection, how would the `GetDetails` method link up to the view in any way? Could you perhaps provide an expanded code sample? I love MVVM but I feel I'm missing something fundamental. – Ryan Amies Aug 16 '13 at 21:46
  • Added a couple more details to my answer – vidalsasoon Aug 17 '13 at 12:24