Страницы

Поиск по вопросам

среда, 10 октября 2018 г.

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

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


Ответ

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

Комментариев нет:

Отправить комментарий