Я в процессе значительных усилий по внедрению NHibernate в нашу кодовую базу.Я подумал, что мне придется использовать какой-то DI-контейнер, чтобы я мог внедрить зависимости в сущности, которые я загружаю из базы данных.Я выбрал Unity в качестве этого контейнера.
Я рассматриваю возможность использования механизма перехвата Unity для добавления аспекта транзакции в мой код, поэтому я могу сделать, например, следующее:
class SomeService
{
[Transaction]
public void DoSomething(CustomerId id)
{
Customer c = CustomerRepository.LoadCustomer(id);
c.DoSomething();
}
}
и *Обработчик 1006 * позаботится о создании сеанса и транзакции, фиксации транзакции (или отмене исключения) и т. Д.
Я обеспокоен тем, что использование такого вида перехвата свяжет меня с использованием Unity довольномного везде в коде.Если я представлю аспекты таким образом, то никогда не буду звонить new SomeService()
, иначе я получу услугу, в которой нет транзакций.Хотя это приемлемо в производственном коде, в тестах это кажется слишком сложным.Например, я должен был бы преобразовать это:
void TestMethod()
{
MockDependency dependency = new MockDependency();
dependency.SetupForTest();
var service = SomeService(dependency);
service.DoSomething();
}
в это:
void TestMethod()
{
unityContainer.RegisterType<MockDependency>();
unityContainer.RegisterType<IDependency, MockDependency>();
MockDependency dependency = unityContainer.Resolve<MockDependency>();
dependency.SetupForTest();
var service = unityContainer.Resolve<SomeService>();
service.DoSomething();
}
Это добавляет 2 строки для каждого фиктивного объекта, который я использую, что приводит к довольнонемного кода (в наших тестах используется много макетов с отслеживанием состояния, поэтому тестовый класс нередко имеет 5-8 фиктивных объектов, а иногда и больше.)
Я не думаю, что автономное внедрение поможетздесь: мне нужно настроить внедрение для каждого класса, который я использую в тестах, потому что возможно добавление аспектов в класс после написания теста.
Теперь, если я откажусь от использования перехватаВ итоге я получу:
class SomeService
{
public void DoSomething(CustomerId id)
{
Transaction.Run(
() => {
Customer c = CustomerRepository.LoadCustomer(id);
c.DoSomething();
});
}
}
, который, по общему признанию, не так хорош, но тоже не кажется таким уж плохим.
Я даже могу настроить перехват моего собственного бедняка:
class SomeService
{
[Transaction]
public void DoSomething(CustomerId id)
{
Interceptor.Intercept(
MethodInfo.GetCurrentMethod(),
() => {
Customer c = CustomerRepository.LoadCustomer(id);
c.DoSomething();
});
}
}
и тогда мой перехватчик может обработать атрибуты для класса, но я все еще могу создавать экземпляр класса, используя new
и не беспокоиться о потере функциональности.
Есть ли лучший способиспользуя перехват Unity, это не заставляетмне всегда использовать его для создания экземпляров моих объектов?