ASP.NET MVC - Использование UnitOfWork
В настоящее время я работаю над веб-приложением, которое состоит из 6 слоев:
- Веб (ссылка на ViewModels и контроллеры)
- ViewModels
- Контроллеры
- Услуги (ссылка на данные и объекты)
- Данные (ссылка на сущности)
- юридические лица
Я пытаюсь реализовать шаблон "UnitOfWork", и поэтому у меня есть класс, который вводится DI для этой работы, что позволяет выполнять.commit() в результате действия в контроллере, когда я заканчиваю с база данных.
Теперь мой вопрос... Где должен быть размещен этот класс UnitOfWork? В данный момент это происходит на моем уровне данных, но для этого требуется, чтобы уровень контроллера ссылался на уровень данных и уровень обслуживания, что, на мой взгляд, странно... Должен ли я переместить класс / интерфейс UnitOfWork на уровень обслуживания и использовать DI?
3 ответа
Если вы не используете шаблон Repository на своем слое данных, вы тратите свое время.
Задача UoW - обрабатывать изменения в нескольких экземплярах репозитория, это делается следующими способами:
- Единица работы выводится из фактического базового контекста (DataContext - L2SQL, ObjectContext/EF)
- Репозитории берут Единицу Работы в своем ctor.
Единица работы делает две вещи:
- Есть
Commit()
метод - Выставьте базовый объект / сущность, установленную в хранилище.
Немного сложно все настроить, но как только вы это сделаете, процесс должен выглядеть следующим образом:
- Контроллер получает услугу и единицу работы (оба через интерфейсы)
- Контроллер вызывает метод для службы ("CustomerServices.AddOrder ()")
- Метод вызова сервисов в репозитории
- Репозиторий вызывает метод "Добавить" для объекта / сущности "Порядок"
- Контролер передает единицу работы
По сути, каждый слой берет экземпляр "следующего слоя" в своем конструкторе. Все должно быть DI'ed и управляемым интерфейсом. UoW не полагается ни на что - но репозиторий полагается на него для сохранения во "внутренней памяти" (ORM), тогда UoW "Commit" вытолкнет изменения в базу данных (в основном, обертывает метод "SaveChanges").
Поскольку Единица работы - это инфраструктура / постоянство / база данных / транзакционная проблема, она должна перейти на уровень данных. Должны быть указаны только контроллерами.
НТН.
IUnitOfWork должен быть интерфейсом для уровня данных. Когда запрос приходит в контроллер, вызывайте сервисные методы, если вам требуется CRUD, вы должны вызвать UnitOfWork. Вы можете использовать Session Per Request по вызову UnitOfWork в Global.asax Request_Start и фиксировать работы в Request_End.
Я реализовал свой IUnitOfWork
класс для передачи непосредственно в мои контроллеры MVC (вводится через Castle Windsor). Затем мой контроллер передает его любым объектам службы, которые он создает.