Благодаря Devoteam Luxembourg я на самом деле настраиваю архитектуру Silverlight, но это была не первая моя практика … Я уже настроил архитектуры Silverlight поверх уровня обслуживания. В большинстве случаев я нашел несколько отличных ярлыков, несколько советов о том, что можно сделать, а что нельзя. Мои результаты мозгового штурма будут объяснены в этой статье.
Использует случаи
В течение нескольких лет я практиковал Silverlight в бизнес-контексте. В каждом случае клиенты просят нас разработать пользовательский интерфейс с бизнес-логикой и постоянством. В большинстве случаев клиенты хотели приложение CRUD с приятным пользовательским интерфейсом.
цель
Эти приложения должны были управлять сложными данными и для каждого типа данных должны:
- Иметь вид только для чтения,
- Иметь вид записи,
- Управление сложными свойствами / свойствами навигации путем добавления или удаления вложенных элементов,
- Иметь корпоративный взгляд и инновационный пользовательский опыт,
Я предложил примерно ту же архитектуру, даже с учетом моего опыта… Silverlight поверх SOA был для меня решением по многим требованиям.
- Multi-User
- Меньше проблем с развертыванием
- Выставлять услуги / ресурсы для других
Образец моих последних пакетов проекта
Значок (L) говорит, что файлы «добавляются как ссылки» в рамках проекта. В этом случае изменение его в первой и реальной ссылке говорит о том, что вы меняете его там, где файл связан.
Инструменты и Технологии
Через
NuGet я использую
MVVM Light , Entity Framework 4, а также генерацию кода T4 от Microsoft с
редактором T4 .
Подробно
На основе базы данных я создаю файл EDMX, который генерирует слой постоянства и файлы POCO. Эти файлы POCO включают в себя весь уровень персистентности структуры сущностей. Также на основе файла EDMX файл T4 может генерировать DTO в формате MVVM Light и конфигурации AutoMapper.
Генератор T4 — это форк версии Self Tracking Entity. Он генерирует один файл на класс для DTO и один глобальный файл, который определяет конфигурацию AutoMapper.
В этой конфигурации изменение формата данных и источника данных позволяет разработчикам быть более реактивными. Они должны настроить веб-сервисы и представления.
Выбор DTO позволяет разработчикам расширять сгенерированный пакет с помощью пользовательских DTO. Например, в функциях автозаполнения.
Сгенерированный MVVM DTO
Этот файл будет содержать одно свойство MVVM для каждого соответствующего свойства в данном классе (например, с помощью вызова RaisePropertyChange).
Сгенерированная конфигурация AutoMapper
Он будет генерировать конфигурацию из POCO в DTO (полная копия) и из DTO в POCO, предотвращая копирование свойств первичного ключа, комплекса и навигации.
Передача данных
Теперь мы опишем, как данные будут развиваться в архитектуре.
Данные на самом деле хранятся в базе данных. Посредством запроса LinQ бизнес-уровень найдет данные, а Entity Framework заполнит POCO. По умолчанию отложенная загрузка отключена. Это предотвратит загрузку всей базы данных с помощью AutoMapper или сериализации. Пользователи должны сказать, какие данные необходимы. После заполнения POCO AutoMapper может передать данные из него в новый DTO перед отправкой через WCF.
Silverlight получит данные и может напрямую связать их с представлениями.
С другой стороны, Silverlight может изменять основные данные и отправлять их обратно на сервер. Бизнес-уровень получит DTO. Если он уже существует, загрузите его и запишите поверх благодаря AutoMapper. Если он не существует, он добавит данные в слой постоянства.
С помощью статического метода можно «объединять списки» для иерархических объектов. Вы можете найти скрипт ниже и узнать цель функции. Это основано на
предложенном здесь решении потока stackoverflow .
public static void Reconcile(EntityCollection databaseList, ObservableCollection dtoList, Func keySelector, Func keySelectorDTO, Func databaseFinder) where T : class where TDTO : class { Dictionary databaseDict = databaseList.ToDictionary(key => keySelector(key)); foreach (TDTO dtoObj in dtoList) { int key = keySelectorDTO(dtoObj); T databaseObj = null; if (databaseDict.TryGetValue(key, out databaseObj)) { databaseDict.Remove(key); } else { T databaseObjFound = databaseFinder(key); if (databaseObjFound != null) { databaseList.Add(databaseObjFound); } } } foreach (T removed in databaseDict.Values) { databaseList.Remove(removed); } }
Проверка
Валидация может быть настроена путем создания частичного класса и добавления проверки, помогающей с FluentValidation. Вы можете настроить проверку на стороне сервера и добавить ссылку на частичный класс на стороне клиента. При такой конфигурации
вы можете добавить только клиентскую сторону, только серверную или обе, если хотите .
Детали проверки можно найти здесь.
Эта статья следует за предыдущей:
Часть 1
Теперь мы подробно расскажем об интеграции проверки в сгенерированном контексте.
Вот схема, которая суммирует интеграцию проверки.
- Сгенерированная часть (левая сторона) — это MVVM DTO, обработанная из файла edmx. Этот файл будет связан с моделью на стороне Silverlight. Эта часть абсолютно не связана с проверкой.
- Другой частичный класс (правая сторона) добавляется пользователем и может включать несколько частей информации (дополнительные свойства, методы, …) и, в этом случае, помечать класс и утверждать, что он может быть проверен.
- Последняя часть (ниже) — это определение валидации. Вы можете встроить каждое правило в конструктор класса.
Если вы свяжете в пакете модели Silverlight эти три класса, вы получите выгоду от проверки на стороне клиента. Эта модель проверки полностью интегрирована с технологией Silverlight. Настройка проверки в представлении путем добавления «ValidatesOnDataErrors = True». С этой модификацией все проблемы проверки будут подняты пользователю (при привязке обновления). Бонус должен добавить «ValidatesOnExceptions = True». Теперь вы будете выдавать предупреждения проверки для системных исключений (например, проблема преобразования, установка строки в свойстве float …)
Последний шаг этой статьи — разоблачение того, что я обычно использую в программах Silverlight / WPF. Некоторые из них из других источников.
поведения
- BindVisualStateBehavior : свяжите свойство enum вашей виртуальной машины и, при изменениях, вызовите «состояние изменения» в представлении. Основная цель состоит в том, чтобы определить состояние Laoding / Loaded, состояние Error / NoError, состояние Application и позволить пользователю управлять вашим приложением silverlight только путем изменения значения enum.
- BackToStateBehavior: в конкретном действии установите перечисление для указанного привязанного свойства.
- KeyPressSelecterComboboxBehavior : при нажатии клавиши с буквой пользователя выберите элемент комбинированного списка, начиная с элемента.
- NotNullCheckboxBehavior : когда кто-то устанавливает пустое значение для флажка, оно автоматически изменяется на false. Борьба с плохим форматом базы данных ?
- RadioButtonToValueBehavior : при включении радио установите для указанного значения связанное свойство. Полезно, чтобы связать группу переключателей со значением.
- SecurityBehavior : это поведение связано со списком «Роль» и, если указанная роль не найдена в списке, оно скрывает связанный объект.
- UpdateBindingOnTextChangedBehavior : при каждом нажатии клавиши обновлять привязку текста.
- ValueToVisibilityBehavior : показывать связанный объект, только если связанное свойство равно указанному значению.
Преобразователи
- BirthDateConverter : простой конвертер для изменения DateTime в указанный формат.
- VisibilityConveter (& Inverted version) : преобразование логического значения в видимость
- VisibilityFromDataConverter (& Inverted version) : проверить, не содержат ли данные нулевые значения, и преобразовать результат в видимость.