Uploaded by Дима Грибовский

Unit of Work

advertisement
Unit of Work - это паттерн определяющий логическую транзакцию т.е. атомарную синхронизацию
изменений в объектах, помещённых в объект UoW с хранилищем (базой данных).
Фильтр кода Expression<Func<TEntity, bool>> означает, что вызывающий объект предоставит
лямбда-выражение на основе типа TEntity, и это выражение вернет логическое значение.
Например, если репозиторий создается для типа сущности Student, код в вызывающем методе
может указывать student => student.LastName == "Smith" для параметра фильтра.
Код Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy также означает, что
вызывающий объект предоставит лямбда-выражение. Но в этом случае входом для выражения
является объект IQueryable для типа TEntity. Выражение вернет упорядоченную версию этого
объекта IQueryable. Например, если репозиторий создается для типа сущности Student, код в
вызывающем методе может указывать q => q.OrderBy(s => s.LastName) для параметра orderBy.
Класс единицы работы служит одной цели: убедиться, что при использовании нескольких
репозиториев они совместно используют один контекст базы данных. Таким образом, когда
единица работы завершена, вы можете вызвать метод SaveChanges для этого экземпляра контекста
и быть уверенным, что все связанные изменения будут скоординированы. Все, что нужно классу, —
это метод Save и свойство для каждого репозитория. Каждое свойство репозитория возвращает
экземпляр репозитория, который был создан с использованием того же экземпляра контекста базы
данных, что и другие экземпляры репозитория.
Каждое свойство репозитория проверяет, существует ли уже репозиторий. Если нет, он создает
экземпляр репозитория, передавая экземпляр контекста. В результате все репозитории используют
один и тот же экземпляр контекста.
----------------------------------------------------------------------------------------------------------------------------------------
В приложениях часто юзается шаблон Repository для инкапсуляции логики работы с БД.
Часто приходится оперировать множеством сущностей и моделей, для управления
которыми создается также большое количество репозиториев. Паттерн Unit of Work
помогает упростить работу с различными репозиториями и дает уверенность, что все
репозитории будут использовать один и тот же DbContext.
Так же использование шаблона Репозиторий и UoW позволяет создать правильную
структуру для развертывания приложения и внедрения DI практик которые в том числе
помогают в тестировании проекта:
Паттерн Unit of Work как правило не является полностью самостоятельным, обычно тесно
связан с паттерном Identity Map и Metadata Mapping, которые реализованы внутри
DbContext'a (если вы используете Entit Framework). Вдаваться в подробности реализации
контекста не буду. Опишу пару слов про эти шаблоны PoeAA:
Identity Map — реализует сохранение карты созданных объектов, взятых из стореджа с
тем чтобы гарантировать что одна единица информации из хранилища представлена
ровно одним экземпляром объекта данных в приложении. Это помогает избежать
конфликтов изменений т.к. не допускает ситуации когда два объекта, представляющих
один и тот же элемент данных в хранилище, изменены по-разному (по сути реализует
уровень изоляции во избежание коллизий данных)
Metadata Mapping — Поскольку для вычисления разницы (и определения того что и
каким образом что и где должно быть изменено в хранилище (Tracking Changes) )
необходимо знать какие данные и как именно хранятся в объектах - как правило это
реализуется с помощью MetaData Mapping паттерна, описывающего связь между
содержимым БД (к примеру таблицами и столбцами базы данных) и классами /
свойствами объектов.
Download