Вероятно, есть несколько способов, как использовать это, поэтому я опишу тот, который я нашел полезным.
Imho место для определения UoW находится в логике приложения - логике, которая вызывает ваш бизнес-уровень (бизнес-сервисы). Причина этого заключается в том, что UoW должен представлять логическую бизнес-операцию - логика приложения (или фасад службы в случае удаленных вызовов) определяет, что такое логическая транзакция. Так, например, в MVC вы можете использовать архитектуру, в которой каждое действие контроллера представляет собой одно UoW:
public class MyController : Controller
{
public MyController(IFirstService firstService, ISecondService secondService,
IUnitOfWork unitOfWork)
{ ... }
[HttpPost]
public ActionResult SomeAction(Model data)
{
_firstService.SomeProcessing(data);
_secondService.SomeProcessing(data);
_unitOfWork.SaveChanges();
return RedirectToAction(...);
}
}
В этом примере мой контроллер зависит от двух бизнес-сервисов, и действие вызывает их оба - UoW, затем сохраните изменения, выполненные обеими сервисами. Вот почему я считаю, что UoW должен быть доступен в контроллере, потому что, если у вашего прикладного уровня нет доступа к UoW, вы не можете составить (повторно использовать) свою логику из нескольких сервисных вызовов (потому что каждый из них, вероятно, вызывает свои собственные SaveChanges).
Другой подход с сервисным фасадом. Фасад будет публичным интерфейсом вашего бизнес-уровня и будет скрывать состав сервиса:
_firstService.SomeProcessing(data);
_secondService.SomeProcessing(data);
_unitOfWork.SaveChanges();
В этом случае UoW не будет передан контроллеру, а на служебный фасад, а служебный фасад будет введен в контроллер. Вы обязательно будете использовать этот подход, если ваша бизнес-логика будет представлена через веб-сервис (или другую удаленную технологию).
Последняя проблема, с которой вам приходится сталкиваться, это передача UoW сервисам. Службы, а также UoW внедряются в контроллер (презентатор, фасад службы или что-то еще), но в то же время UoW (или ObjectContext) должны быть внедрены в службы, чтобы внутренне используемые репозитории могли работать с ним. Для этого вам нужен правильный менеджер времени жизни IoC, чтобы он возвращал один и тот же экземпляр для всех инъекций в рамках одного и того же «запроса». В случае веб-приложения вам нужен менеджер времени жизни PerHttpRequest (который вы должны реализовать самостоятельно, потому что Unity его не предоставляет).