Внедрение зависимостей с помощью 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 ответ:
Прежде всего я хотел бы заглянуть в класс "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.