Стоит ли перехват накладных расходов, которые он создает? - PullRequest
2 голосов
/ 18 мая 2011

Я в процессе значительных усилий по внедрению 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, это не заставляетмне всегда использовать его для создания экземпляров моих объектов?

1 Ответ

0 голосов
/ 18 мая 2011

Если вы хотите использовать AOP, но заинтересованы в Unity, я бы порекомендовал вам попробовать PostSharp.Это реализует AOP как проверку после компиляции, но не меняет того, как вы используете код во время выполнения.а также профессиональные и корпоративные версии со значительно расширенными наборами функций.

...