Асинхронная отложенная загрузка свойств навигации для отсоединенных объектов с самопроверкой через службу WCF?

У меня есть клиент WCF, который передает объекты самопроверки в приложение WPF, созданное с помощью MVVM. Само приложение имеет динамический интерфейс. Пользователи могут выбирать, какие объекты они хотят видеть в своей рабочей области, в зависимости от того, в какой роли они находятся или какую задачу они выполняют.

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

[WCF] <---> [ClientSide Repository] <---> [ViewModel] <---> [View]

Мои модели являются объектами с самопроверкой. Репозиторий на стороне клиента подключает метод LazyLoad (при необходимости) перед возвратом модели в модель представления, которая ее запросила. Все вызовы службы WCF асинхронны, что означает, что методы LazyLoad также асинхронны.

Фактическая реализация LazyLoad доставляет мне некоторые проблемы. Вот варианты, которые я придумал.

РЕДАКТИРОВАТЬ - Я удалил образцы кода, чтобы упростить чтение и понимание. См. Предыдущую версию вопроса, если вы хотите ее увидеть

Вариант A

Асинхронная отложенная загрузка свойств модели с сервера WCF в Getter

Хорошо: Загрузка данных по запросу чрезвычайно проста. Привязка в XAML загружает данные, поэтому, если элемент управления находится на экране, данные загружаются асинхронно и уведомляют пользовательский интерфейс, когда они появляются. Если нет, ничего не загружается. Например, загрузит данные, однако, если раздел «Документы» интерфейса отсутствует, ничего не загружается.

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

public bool HasDocuments 
{ 
    get { return ConsumerDocuments.Count > 0; }
}

ВАРИАНТ B

Выполнение вызова для загрузки данных вручную, когда это необходимо

Хорошо: Просто реализовать - просто добавьте ] LoadConsumerDocumentsSync () и LoadConsumerDocumentsAsync () методы

Плохо: Необходимо не забыть загрузить данные перед попыткой доступа к ним, в том числе когда они используются в привязках. Это может показаться простым, но это может быстро выйти из-под контроля. Например, у каждого ConsumerDocument есть UserCreated и UserLastModified. Существует DataTemplate, который определяет UserModel со всплывающей подсказкой, отображающей дополнительные данные пользователя, такие как расширение, электронная почта, команды, роли и т. Д. Итак, в моей ViewModel, которая отображает документы, мне нужно было бы вызвать LoadDocuments , а затем выполнить цикл их и вызовите LoadConsumerModified и LoadConsumerCreated . Это тоже могло бы продолжаться ... после этого мне пришлось бы LoadUserGroups и LoadUserSupervisor . Также существует риск возникновения циклических циклов, когда что-то вроде Пользователь имеет свойство Группы [] , а Группа имеет Пользователи [] свойство

ВАРИАНТ C

На данный момент мой любимый вариант ... создать два способа доступа к свойству. Одна синхронизация и одна асинхронная передача. Привязки будут выполняться со свойством Async, и любой код будет использовать свойство Sync.

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

Плохо: Наличие двух способов доступа к одним и тем же данным кажется неэффективным и запутанным. Вам нужно помнить, когда следует использовать Consumer. ConsumerDocumentsAsync вместо Consumer.ConsumerDocumentsSync . Также существует вероятность того, что вызов службы WCF запускается несколько раз, и для этого требуется дополнительное свойство IsLoaded для каждого навигационного свойства, например IsConsumerDocumentsLoaded.

ВАРИАНТ D

Пропустите асинхронную загрузку и просто загрузите все синхронно в сеттеры.

Хорошо: Очень просто, никаких дополнительных действий не требуется

Плохо: Блокирует пользовательский интерфейс при загрузке данных. Не хочу этого.

ВАРИАНТ E

Попросите кого-нибудь из SO сказать мне, что есть другой способ сделать это, и указать мне на образцы кода :)

Другие примечания

Некоторые из NavigationProperties будут загружается на WCF-сервер перед возвратом объекта клиенту, однако другие слишком дороги для этого.

За исключением ручного вызова событий загрузки в варианте C, все это можно сделать с помощью шаблона T4, поэтому мне нужно сделать очень мало кода. Все, что мне нужно сделать, это подключить событие LazyLoad в клиентском репозитории и указать его на правильные вызовы службы.

22
задан Rachel 6 May 2011 в 20:04
поделиться