Точка входа в MVVM: App.xaml.cs или представление?

271
09 декабря 2016, 08:58

Начал изучать MVVM и столкнулся, как наверное и многие другие, с определенным недопониманием. В многочисленных примерах реализации MVVM, доступных в сети, авторы разными способами подходят к точке входа в приложение (могу ошибаться в определении). Некоторые меняют аттрибут StartupUri, другие просто его полностью удаляют и в перегруженном методе OnStartup файла App.xaml.cs вручную создают экземпляр окна и устанавливают ему свойство DataContext. Нашел в сети несколько примеров по MVVM и mvvm-light (пример 1, пример 1, пример 3, пример 4 и пример 5) и в них автор вообще не изменяет App.xaml или App.xaml.cs и только в одном изменяет code-behind (так и не понял как это называется по-русски) представлений.

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

Answer 1

Я предпочитаю не использовать StartupUri, а переопределять OnStartup, и создавать главное окно там ([1], [2], [3]).

Причина в том, что указание StartupUri не позволяет задать DataContext снаружи окна. А хардкодирование DataContext'а внутри XAML неправильно, так как:

  • Согласно паттерну MVVM, View не должно руководить VM, и знать о нём должно как можно меньше. То есть код, обслуживающий UI, не должен создавать себе VM сам.
  • Чаще всего VM должна получить ещё какие-то аргументы в конструкторе (например, модельные объекты), а это не получится сделать, если VM создаётся в XAML'е (откуда XAML может знать о модели?).
  • Иногда перед открытием главного окна нужна дополнительная логика, требующая показа своего маленького окна (например, предложение обновить программу). Код, выясняющий это и при некоторых условиях показывающий дополнительное окно, проще разместить в OnStartup.
  • Главная VM может понадобиться вам для ещё чего-нибудь. Поэтому если её создаёт класс App, он может сохранить ссылку на неё у себя, чтобы другие (например, побочное окно) могли быть привязаны к тому же экземпляру VM. Иначе вам придётся лезть на главной VM в экземпляр главного окна.

В любом случае, MVVM не догма, делайте так, как вам удобнее.

READ ALSO
Как создать папку с текстовыми файлами в проекте и пользоваться ими?

Как создать папку с текстовыми файлами в проекте и пользоваться ими?

Хочу добавить в проект несколько csv файлов и пользоваться ими, как текстовыми ресурсамиНу и чтобы лежали вместе в папке для порядка

370
C# selenuim phantomJS error: can't find JQuery

C# selenuim phantomJS error: can't find JQuery

ПриветствуюРешил поработать с selenium в C# посредством веб-драйвера phantomJS, но при запуске phantomjs

275