ObservableCollection в сервисном уровне приложения WPF MVVM

Примеры приложений WPF MVVM, которые я видел в Интернете, рассматривают VM как уровень, который взаимодействует с сервисным уровнем, который либо использует "старые" события из внешней библиотеки, либо взаимодействует с сетью, используя HTTP или что-то еще. Но что если я сам соберу все M, V, VM, сервис и другие части? Как правильно выстроить взаимодействие между уровнем сервиса и уровнем viewmodel? Можно просто поставить ObservableCollection<OrderModel> в сервис и вернуть его как есть из viewmodel для представления, или это считается плохим подходом, и есть лучшие альтернативы?

3 ответа

Решение

Вы можете сделать это - конечно, вы можете. Основной причиной такого действия было бы уменьшение дублирования в нескольких приложениях WPF.

Однако в некоторых сценариях у вас может возникнуть проблема, в зависимости от реализации вашего уровня обслуживания / уровня данных, - это долгосрочные службы, которые в свою очередь используют соединения с базой данных. ObservableCollections заманчивы с точки зрения того, чтобы сервисный уровень автоматически синхронизировал изменения, внесенные приложением, в хранилище данных; однако это усложняется, когда вы хотите сообщить об изменениях, которые происходят из самих данных (т.е. в ответ на какой-то другой процесс, который создает / изменяет данные).

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

Таким образом, вы стараетесь поддерживать один экземпляр в актуальном состоянии. Если ваши сервисы связаны с базой данных, то, если вы не закодируете какую-либо форму длительного процесса мониторинга в вашем сервисе, единственный простой способ поддерживать ObservableCollection в актуальном состоянии после того, как он был отключен, - это удерживать соединения с базой данных / контексты (в случае Linq to Sql или EF) открываются - потому что иначе связанные объекты и т. д. не смогут быть извлечены (если вы не заставите все объекты быть прочитанными за один раз - что не масштабируется).

Итак, можно написать некоторую форму уровня управления, который может управлять соединениями для вас - но в дополнение к неизбежному опросу или, возможно, к уведомлениям SQL Server, которые вы могли бы использовать, я считаю, что код может быть довольно сложным.

Тем не менее, это действительно зависит - на эту конкретную проблему стоит обратить внимание, но, возможно, у вас есть архитектура и среда, в которой такие вещи просто не имеют значения.

Мой совет, если хочешь попробовать - давай. Для меня? Я думал об этом - и помимо добавления INotifyPropertyChanged к некоторым моделям доменов, я придерживаюсь идеи, что приложение имеет свою собственную виртуальную машину. Несколько приложений могут использовать одну и ту же виртуальную машину, но это не будет внутренним по отношению к самому уровню обслуживания.

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

Я бы соблазнился использовать ObservableCollection только с той точки, в которой "наблюдаемый" аспект имеет значение, как правило, это виртуальная машина, выставляющая что-то на V. Далее вниз по стеку (то есть M) я бы соблазнился придерживаться с более общими вещами, такими как списки и коллекции (если вам не нужно, чтобы все было иначе). Виртуальной машине достаточно просто создать ObservableCollection на основе любого старого IEnumerable в любом случае.

Вполне разумный вопрос, тем более, что размещение ObservableCollection в пространстве имен System.Collections может показаться, что Microsoft не особенно думает об этом как о специализированном классе (и, конечно, не о wpf-специфичных).

Я бы не стал этого делать по ряду причин. Они задокументированы здесь: Распространенные ошибки с наблюдаемой коллекцией

Автор проходит через несколько ошибок, которые люди совершают с ними, в том числе используя их на уровне сервиса.

Другие вопросы по тегам