Фасад доступа к данным — Адаптер записи, Трансляторы

Адаптеры записи

Как и в случае с адаптерами для чтения, большую часть работы можно вынести в абстрактный класс. Интерфейс IWriteAdapter необходим опять же в целях обнаружения классов.

Если вы взглянете на метод InfrastructureFacade.Commit() то увидите, что получение всех адаптеров для записи получается из StructureMap скопом по одному только интерфейсу, что весьма удобно, так как они нужны всегда все разом для определения очередности работы.

IWriteAdapter

В интерфейс вынесены метод и свойство необходимые для работы в классе фасада, а именно Save() и Sequence.

Теперь можно переходить к рассмотрению «мяса», основной работы по сохранению данных.

Подробнее

Фасад доступа к данным — Фасад и Адаптер чтения

Фасад

Теория

Кажется, все приготовления прошли, необходимые концепции упомянул и теперь можно перейти непосредственно к реализации фасада. Интерфейс фасада состоит всего из двух методов, которых нам хватит для всех целей приложения.

Как вы можете заметить, интерфейс фасада содержится в модуле домена, тогда как реализация будет в модуле инфраструктуры – применяем инверсию зависимостей, так как домен не должен зависеть от других частей системы.

Про Unit of Work (UoW) рассказано было ранее, паттерн Specification так же уже рассматривался, так что на этих типах данных останавливаться не будем.

Общий принцип работы такой:

  • Получаем фасад;
  • Вызываем метод получения доменных данных, в который передаем ограничивающие условия, которым должны соответствовать элементы;
  • Что-то делаем с данными, работаем с UoW;
  • Вызываем метод сохранения UoW.

Фасад доступа к данным — Подготовка

На основе LINQ to SQL

Сложность по шкале Microsoft 300-400

Сразу признаюсь, что я люблю Linq2Sql и не люблю Entity Framework. Люблю компактные API и не люблю развесистые классы с кучей методов служебных выставленных наружу. Может по этим причинам, а может быть по каким-то еще, но я использую схему доступа к данным, которую собираюсь описать ниже, уже несколько лет. По большей части меня она радует и выполняет свои задачи хорошо для большинства заданий возникающих на работе.

Вводная часть

Как уже ясно из названия, речь пойдет о паттерне Фасад. Вот что нам говорит википедия по поводу этого шаблона:

Шаблон Facade (Фасад) — Шаблон проектирования, позволяющий скрыть сложность системы путем сведения всех возможных внешних вызовов к одному объекту, делегирующему их соответствующим объектам системы.

Однако сам по себе фасад достаточно тривиален и ограничиться только описанием применимости паттерна в случае баз данных было бы не очень интересно и информативно. Я планирую рассмотреть всю цепочку классов и данных, которые участвуют в получении данных, от записей в базы данных до доменных классов. Описать пути преобразования данных, оптимизацию запросов, сложные моменты в реализации, ограничения технологии, случаи, когда данный подход не оправдает себя.

Итогом работы будет являться использование фасада в таком духе:

Т.е. надо будет только указать фасаду какой тип доменных данных вы хотите получить и с какими ограничениями. В данном случае ограничений на данные нет, т.е. в результате выполнения запроса получим всех заказчиков из базы.

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

Подробнее

Автообнаружение и регистрация классов в StructureMap

Уровень подготовки по шкале MS: 400

Некоторое время назад  я рассказывал про чудесный IoC\DI контейнер StructureMap. На тот момент я описал основные приемы работы, скорее как справочник, показавший возможности, без углубления в конкретные темы. На этот раз я хочу рассказать о возможности автоматического обнаружения и регистрации классов средствами StructureMap.

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

Дальнейшие примеры покажут, как работать с обнаружением только по интерфейсу\базовому классу, а так же как работать при именовании классов по соглашениям (Convention over Configuration).

Вводная

Сначала достаточно простой пример. Пусть у нас есть множество классов для трансляции данных из базы, все они наследованы от базового класса. Т.е. что-то в духе:

 

И таких классов достаточно много, всех их регистрировать вручную не очень хочется, т.к. это выглядит ужасно в коде и писать долго. Регистрация таких адаптеров может занять экран, а то и два. Гораздо лучше поднапрячь извилины и записать это в несколько строк.

Итак, StructureMap предоставляет метод Scan, который пробегает по интересующим нас сборкам или папкам и регистрирует подходящие объекты. Для того чтобы метод Scan нашел и зарегистрировал типы необходимо соблюдение нескольких условий:

  • Тип должен быть явным, дженерик типы не регистрируются автоматически;
  • Тип должен иметь публичный конструктор;
  • Конструктор не может иметь аргументов примитивных типов;
  • Множественное регистрирование не допускается.

Указание сборки для сканирования можно задать несколькими способами:

  • Явно прописать имя сборки или же передать ее саму;
  • Обратиться к вызывающей сборке;
  • Найти сборку содержащую определенный тип;
  • Найти сборки по определенному пути.