Внедрение зависимостей с помощью MVVM и дочерних окон


Я использую MVVM Light и в настоящее время использую SimpleIoC, который поставляется вместе с пакетом. Я немного застрял с инъекцией зависимости. У меня есть куча сервисов, которые я хочу использовать в своих моделях представления, однако большинство окон-это парадигма редактирования списка, то есть один экран перечисляет все типы Person, а затем вы можете добавить или отредактировать Person через новый экран.

Когда я делал весь код в коде за моим кодом для добавления и редактирования записи было как образом:

Вид

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

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

Модель Вида

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

Конструктор TypeDetails выглядит следующим образом:

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

Что лучше всего было бы реализовать этот тип функциональности с помощью MVVM Light? Я использовал класс ViewModelLocator для экранов списков, однако я не вижу способа сделать это с помощью SimpleIoC. Мой путь до сих пор состоял в том, чтобы сохранить конструктор таким же, который работает нормально, пока мне не нужно ввести зависимости в TypeDetailsViewModel, такие как обслуживание. С помощью сервиса Конструктор TypeDetailsViewModel будет иметь вид:

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

Но это означает, что в моем конструкторе представления я должен построить эти зависимости по одному за раз и вручную ввести их...

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

Есть ли лучший способ сделать это?

1 2

1 ответ:

  • Прежде всего я хотел бы заглянуть в класс "RelayCommand", который является частью MVVM Light. Это устранит необходимость в событиях в вашем коде позади. Начните с этого.

  • Вы всегда должны отдавать предпочтение "инъекции конструктора" вместо ServiceLocator (например: SimpleIoC.Текущий.GetInstance())

  • Ваш конструктор ViewModel должен только вводить службы, а не примитивные типы, такие как "int". В вашем примере "int id" должен быть параметром метода, а не впрыснутый.

Пример: вместо этого ваш TypeDetailsViewModel должен выглядеть следующим образом:

public TypeDetailsViewModel(ISomeService someService)
{
     TypeDetail GetDetailsCommand(int id)
     {
        ...
     }
}
  • Наконец, ваши модели никогда не должны иметь никаких ссылок на ваши модели просмотра.

  • Для вашего DataContext можно использовать ViewModelLocator (ViewModels в ViewModelLocator MVVM Light)

  • Чтобы подключить вид и ViewModel для использования GetDetailsCommand, можно использовать поведение EventToCommand (http://msdn.microsoft.com/en-us/magazine/dn237302.aspx ). пример: событие OnLoaded в представлении вызывает GetDetailsCommand в вашей ViewModel.