Я пытаюсь избежать этой ситуации, структурируя такие вещи:
public class ContactService : IContactService
{
private readonly IContactRepository repository;
private readonly IValidator<Contact> validator;
private readonly IUnitOfWork unitOfWork;
public ContactService(
IContactRepository repository,
IValidator<Contact> validator,
IUnitOfWork unitOfWork)
{
this.repository = repository;
this.validator = validator;
this.unitOfWork = unitOfWork;
}
public void Add(Contact contact)
{
if (!validator.IsValid(contact)) throw new ArgumentException();
try
{
unitOfWork.Start();
repository.Save(contact);
unitOfWork.Commit();
}
catch
{
unitOfWork.Rollback();
throw;
}
}
}
С этим базовым шаблоном Unity может создать ваш сервис со всеми его зависимостями, и вы не столкнетесь с проблемой, внедрив контакт. Репозиторий можно использовать в качестве абстракции или просто напрямую использовать вашу любимую среду доступа к данным, такую как EF, NHibernate или обычный старый Ado.Net, если вы так катаетесь.
Поскольку метод try catch повторяется, вы можете использовать метод расширения для сжатия вашего кода следующим образом:
public void Add(Contact contact)
{
if (!validator.IsValid(contact)) throw new ArgumentException();
unitOfWork.Execute(() => repository.Save(contact));
}
Метод расширения выглядит следующим образом:
public static class UnitOfWorkExtensions
{
public static void Execute(this IUnitOfWork unitOfWork, Action action)
{
try
{
unitOfWork.Start();
action.Invoke();
unitOfWork.Commit();
}
catch
{
unitOfWork.Rollback();
throw;
}
}
}
Подробнее об этом: http://www.agileatwork.com/refactoring-c-style/
Большим преимуществом структурирования вашего кода таким образом является то, что вы можете воспользоваться механизмом перехвата Unity и выполнять множество интересных вещей, таких как перемещение кода единицы работы в аспект (атрибут):
[UnitOfWork]
public void Add(Contact contact)
{
if (!validator.IsValid(contact)) throw new ArgumentException();
repository.Save(contact);
}
Вы можете использовать похожую технику для добавления дополнительных действий, таких как ведение журнала, обработка исключений и безопасность.