Я прошу прощения за длинный вопрос, это звучит немного как напыщенная речь, но я обещаю, что это не так! Я кратко изложил свой вопрос (ы) ниже
В мире MVC все просто. Модель имеет состояние, представление показывает модель, а контроллер выполняет какие-либо действия с моделью (в основном), контроллер не имеет состояния. Для этого у Контроллера есть некоторые зависимости от веб-сервисов, хранилища, всего. Когда вы создаете экземпляр контроллера, вы заботитесь о предоставлении этих зависимостей, и ничего больше. Когда вы выполняете действие (метод в Controller), вы используете эти зависимости для извлечения или обновления Модели или вызова какой-либо другой доменной службы. Если есть какой-либо контекст, скажем, что какой-то пользователь хочет видеть детали определенного элемента, вы передаете Id этого элемента в качестве параметра для Action. Нигде в контроллере нет ни одной ссылки на какое-либо состояние. Все идет нормально.
Введите MVVM. Я люблю WPF, я люблю привязку данных. Я люблю фреймворки, которые делают привязку данных к ViewModels еще проще (с использованием Caliburn Micro atm). Я чувствую, что в этом мире все не так просто. Давайте снова выполнить упражнение: модель имеет состояние, вид показывает модель представления, и ViewModel делает материал к / с моделью ( в основном), модель представление действительно есть состояние! (уточнить, может быть , он делегирует все свойства в одной или нескольких моделей, но это означает , что он должен иметь ссылку на одну сторону модели или другой, что государство само по себе) Для того, чтобы сделатьВещи ViewModel имеют некоторые зависимости от веб-сервисов, репозитория, лота. Когда вы создаете экземпляр ViewModel, вы заботитесь о предоставлении этих зависимостей, а также о состоянии. И это, дамы и господа, раздражает меня до бесконечности.
Всякий раз, когда вам нужно создать экземпляр ProductDetailsViewModel
из ProductSearchViewModel
(из которого вы позвонили, ProductSearchWebService
который в свою очередь вернулся IEnumerable<ProductDTO>
, все еще со мной?), Вы можете сделать одну из следующих вещей:
- позвоните
new ProductDetailsViewModel(productDTO, _shoppingCartWebService /* dependcy */);
, это плохо, представьте себе еще 3 зависимости, это означает, чтоProductSearchViewModel
необходимо учитывать и эти зависимости. Также изменение конструктора является болезненным. - Вызовите
_myInjectedProductDetailsViewModelFactory.Create().Initialize(productDTO);
, фабрика просто Func, они легко генерируются большинством IoC-фреймворков. Я думаю, что это плохо, потому что методы Init - это утечка абстракции. Вы также не можете использовать ключевое слово readonly для полей, которые установлены в методе Init. Я уверен, что есть еще несколько причин. - вызов
_myInjectedProductDetailsViewModelAbstractFactory.Create(productDTO);
Итак ... это шаблон (абстрактная фабрика) , которая, как правило , рекомендуется для такого рода проблемы. Я думал, что это был гений, так как он удовлетворял мою тягу к статической типизации, пока я на самом деле не начал использовать его. Объем стандартного кода, я думаю, слишком велик (вы знаете, помимо нелепых имен переменных, которые я использую). Для каждой модели ViewModel, для которой требуются параметры времени выполнения, вы получите два дополнительных файла (заводской интерфейс и реализацию), и вам нужно будет ввести зависимости без времени выполнения, например, 4 дополнительных раза. И каждый раз, когда меняются зависимости, вы можете изменить их и на фабрике. Такое ощущение, что я даже больше не использую DI-контейнер. (Я думаю, что у Castle Windsor есть какое-то решение для этого [со своими собственными недостатками, поправьте меня, если я ошибаюсь]). - сделать что-нибудь с анонимными типами или словарем. Мне нравится моя статическая типизация.
Так что да. Смешивание состояния и поведения таким образом создает проблему, которой вообще нет в MVC. И я чувствую, что в настоящее время нет действительно адекватного решения этой проблемы. Теперь я хотел бы наблюдать некоторые вещи:
- Люди на самом деле используют MVVM. Таким образом, они либо не заботятся обо всем вышеперечисленном, либо у них есть какое-то блестящее другое решение.
- Я не нашел подробного примера MVVM с WPF. Например, пример проекта NDDD очень помог мне понять некоторые концепции DDD. Мне бы очень понравилось, если бы кто-то мог указать мне в направлении чего-то похожего для MVVM / WPF.
- Может быть, я неправильно делаю MVVM, и я должен перевернуть свой дизайн с ног на голову. Может быть, у меня не должно быть этой проблемы вообще. Ну, я знаю, что другие люди задавали тот же вопрос, поэтому я думаю, что я не единственный.
Подвести итоги
- Правильно ли я пришел к выводу, что наличие ViewModel в качестве точки интеграции как состояния, так и поведения является причиной некоторых трудностей с шаблоном MVVM в целом?
- Является ли использование шаблона абстрактной фабрики единственным / лучшим способом создания экземпляра ViewModel статически типизированным способом?
- Есть ли что-то похожее на детальную справочную реализацию?
- Имеет ли много моделей ViewModel с состоянием / поведением запах дизайна?