Как создать несколько экземпляров ViewModel в C #, используя Ninject, избегая при этом запахов кода? - PullRequest
0 голосов
/ 09 июня 2018

На мой вопрос есть две части.

Первая: как мне создать несколько экземпляров класса ViewModel с помощью внедрения зависимостей?Пример;

Я создаю приложение WPF с использованием шаблона MVVM, Dependency Injection с Ninject и SQLite Database с EntityFramework.Core.Он структурирован так:

  • У меня есть View, скажем Tier1View, который связан с ViewModel, Tier1ViewModel.
  • В пределах Tier1View - ItemsControl с DataTemplate Tier2UserControl, ItemSource для ItemsControl - ObservableCollection<Tier2ViewModel>, эффективно Binding Data Context для каждого Tier2UserControl к экземпляру Tier2ViewModel.
  • В свою очередь каждый Tier2UserControl имеет ItemsControl Tier3UserControl, привязанный к ObservableCollection<Tier3ViewModel>.

, поскольку коллекции моделей уровня Tier2 и Tier3 имеют неопределенный размер во время компиляциипоскольку они полагаются на таблицы в базе данных для исходных данных и могут быть изменены во время выполнения, это исключает возможность использования инжектора Constructor таким грубым способом, как в этом примере (до такой степени, что мне стыдно даже рассматривать это).

public Tier1ViewModel(ITier2ViewModel firstInstance, ITier2ViewModel secondInstance, ...)
{
    Collection.add(firstInstance);
    Collection.add(secondInstance);
    ...
}

Как создать несколько экземпляров зависимости в одном классе?Ранее было предложено, чтобы я использовал Factory (который поддерживается Ninject) в вопросе, который я задал для передачи переменных в внедренную зависимость, и я создал успешную реализацию этого.

Collection.Add(IViewModelFactory.CreateTierNViewModel());

и внедрениефабрика в Конструкторе Уровня выше.

Однако это приводит ко второй части моего вопроса.

Каждый экземпляр должен быть идентифицируем в коллекции - следовательно, Run-Time Data должен быть передан каждомуэкземпляр "Создан".

Согласно этой статье , использование фабрики повышает сложность и удобство сопровождения приложения.Что-то, чего я пытаюсь избежать в моей цели лучшего понимания программирования.Это также указывает на то, что данные времени выполнения не должны вводиться в конструкцию объектов, а должны передаваться с помощью методов.

Tier3ViewModels будет отличаться, если содержать уникальные Entities из SQLite База данных (на самом деле это View Models из этих Entities), поскольку Entities может быть известен только в run-time, это правильный подход для создания экземпляра зависимости (из-за отсутствия знаний одругие способы, используя фабрику), а затем есть метод внутри этого ViewModel, который принимает мою сущность в качестве параметра (или, что еще лучше, абстракцию этой сущности, такую ​​как IEntityType)?

var instanceOf = Factory.CreateViewModel();
instanceOf.AddingMethod(IEntity);

IНадеюсь, что это может быть переведено!Заранее спасибо за любую помощь!

1 Ответ

0 голосов
/ 10 июня 2018

Если объект данных должен быть передан в ViewModel, объявите его в конструкторе.

public class Tier2ViewModel
{
   public Tier2ViewModel(Tier2Entity tier2Entity) { //... }
}

Оттуда вы можете создать Tier2ViewModel без использования внедрения зависимостей и просто создать их вручную в вашем Tier1ViewModel class.

public class Tier1ViewModel
{
   private void LoadTier2()
   {
      //TODO: load tier2Entities using EF
      //TODO: foreach tier2Entity, create new Tier2ViewModel
      //TODO: add each Tier2ViewModel instance to ObservableCollection<Tier2ViewModel>
   }
}

Но если вы действительно хотите использовать внедрение зависимостей, то вы на правильном пути использования класса Factory.Но вместо этого передайте объект Entity в метод CreateViewModel.

public interface ITier2ViewModelFactory
{
   Tier2ViewModel CreateViewModel(Tier2Entity tier2Entity);
}
public class Tier2ViewModelFactory : ITier2ViewModelFactory
{
   public Tier2ViewModel CreateViewModel(Tier2Entity tier2Entity)
   {
     return new Tier2ViewModel(tier2Entity);
   }
}
public class Tier1ViewModel
{
   private readonly ITier2ViewModelFactory _tier2ViewModelFactory;
   private void LoadTier2()
   {
      //TODO: load tier2Entities using EF
      //TODO: foreach tier2Entity, call _tier2ViewModelFactory.CreateViewModel(tier2Entity)
      //TODO: add each Tier2ViewModel instance to ObservableCollection<Tier2ViewModel>
   }

Как видите, фабрика добавила еще один уровень абстракции, который мне не нужен ради использования DI для созданияпример.Лично я бы использовал шаблон Factory только в том случае, если создание объекта будет включать сложную логику, которую необходимо проверить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...