MVVM и DI - Как обрабатывать объекты модели? - PullRequest
4 голосов
/ 27 июля 2010

Я использую Caliburn и C #, но я чувствую, что это общий вопрос MVVM / DI.

Допустим, у меня есть модель представления NoteViewModel, которой передан объект модели с именем Note.

Вот код:

class NoteViewModel : PropertyChangedBase
{
  private readonly Note _note;

  public NoteViewModel(Note note)
  {
    _note = note;
  }

  public string Title
  { 
    get { return _note.Title; } 
    set { _note.Title = value; NotifyOfPropertyChange(() => Title); }
  }
}

Прямо сейчас этот объект создается путем вызова new () и передачи объекта модели.

Хорошо, это прекрасно работает, но теперь мне нужно добавить метод, который требует импортированный класс из моего контейнера DI.

Так я просто вызываю ServiceLocator.Current.GetInstance (), чтобы получить его? Или я должен спроектировать эту модель представления, которая будет создаваться через контейнер DI, и каким-то образом настроить способ передачи объекта Note?

Как правильно спроектировать эту модель вида? В основном модель представления «PerInstance», для которой требуется объект модели. У Caliburn есть встроенный способ сделать это?

Ответы [ 3 ]

3 голосов
/ 27 июля 2010

Caliburn имеет интерфейс (IHaveSubject и его типизированную версию IHaveSubject), предназначенный для сценариев такого типа: в основном он позволяет средству конфигурировать ViewModel с «субъектом» после его создания, обычно через контейнер:

class NoteViewModel : PropertyChangedBase, IHasSubject<Note> {
  ...   
} 

myNoteViewModel = ... //obtain an instance
myNoteViewModel.WithSubject(new Note());

Это решение также хорошо интегрируется с инфраструктурой ISubjectSpecification / Conductor.

Несмотря на то, что инициализация после построения - это простое и эффективное решение, вы, возможно, не захотите (с точки зрения чистого проектирования) отказаться от явного конструктора.Параметр, чтобы обеспечить необходимость создания заметки для определения ViewModel.В этом случае я думаю, что вам нужно использовать специфические особенности вашего DI-контейнера, потому что у вас могут быть некоторые параметры конструктора, представляющие «реальный» входной параметр, в то время как другие могут быть служебными зависимостями.

Castle Windsor, дляНапример, имеет приятную особенность, позволяющую быстро построить явную (типизированную) фабрику для вашей ViewModel;фабричный метод позволяет устанавливать только «реальные» параметры, в то время как все зависимости управляются контейнером (подробное описание этой функции Windsor см. в этом посте: http://kozmic.pl/archive/2009/12/24/castle-typed-factory-facility-reborn.aspx)

0 голосов
/ 27 июля 2010

Я также использую ServiceLocator. И я также "чувствую себя грязным" при этом. Но я решил использовать принцип YAGNI и сохранять этот шаблон, пока не найду убедительную отдачу от сложности добавления 5 IServices в мои конструкторы, передав их через 3-4 уровня наследования базовым классам, в которых они необходимы и создание всего через контейнер. Конечно, мое приложение развивается, и YAGNI не всегда длится ...

0 голосов
/ 27 июля 2010

Можете ли вы решить эту проблему, используя модели иерархического представления?

Мне становится все более и более ясным, что мне нужно по одной ViewModel для View и по одной ViewModel на элемент модели или коллекцию при создании более крупного приложения.

Таким образом, мы можем построить ViewModel иерархически, в соответствии с иерархией XAML.

Необходимые объекты могут быть определены или введены на верхнем уровне моделью основного представления приложения. Затем вложенные модели представлений могут получить доступ ко всему, что вы создадите, чтобы сделать их доступными.

Что касается Caliburn, я не знаю каких-либо конкретных сведений об этой платформе, извините.

...