Как настроить необязательный метод перехвата с Ninject? - PullRequest
5 голосов
/ 12 августа 2011

Предположим, у меня есть класс, в котором я хочу иногда * (но теперь всегда) перехватывать некоторые (но не все) методы. Насколько я понимаю, это можно сделать, скажем, с помощью InterceptAround() в моем модуле Ninject (в коде более высокого уровня) или с помощью атрибута, производного от InterceptAttribute этих методов (на уровне реализации). *

Мне не очень нравится первый способ сделать это, потому что потребителю нужно знать детали, будет много классов со многими методами. Но мне также не нравится второй способ, поскольку я не вижу, как отключить (или, скорее, не включить) перехват, поскольку атрибут сливается с кодом.

Есть ли какой-нибудь известный подход для решения этой проблемы?


*: на срок действия заявки.

1 Ответ

6 голосов
/ 15 августа 2011

Звучит так, как будто вы обращаетесь к обычному динамическому перехватчику, так работает расширение Ninject Interception по умолчанию.

Вот пример условного перехвата:

class CustomInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        if (invocation.Request.Method.Name == "MethodToIntercept")
            Console.WriteLine("Intercepted!");
        invocation.Proceed();
    }
}

Вы привязываете его непосредственно к одному классу, например так:

public class MyModule : NinjectModule
{
    public override void Load()
    {
        Bind<IFoo>().To<MyFoo>().Intercept().With<CustomInterceptor>();
    }
}

И это почти все, что вам нужно сделать, если вы хотите динамически перехватить один класс.

Расширения ядра выглядят многообещающими, потому что они позволяют записывать условия непосредственно в объявление:

kernel.Intercept(ctx => ctx.Request.Service == typeof(IFoo))
    .With<CustomInterceptor>();

Однако это не особенно полезно, если вы пытаетесь принимать решения на основе метода выполняется, потому что это дает вам доступ только к контексту привязки, а не к вызову.В основном, это расширение существует, так что вы можете выбрать, какие классы или сервисы (в отличие от методов ) для перехвата во время выполнения.

Лучшепридерживаться синтаксиса привязки и записывать логику запуска или не запуска непосредственно в перехватчик, как показано в первом примере.

Одна важная вещь, на которую следует обратить внимание, это то, что динамический перехватчик будет на самом делезапускать для каждый (публичный / виртуальный) метод для любого класса, к которому он привязан, что может быть очень неэффективно.К сожалению, расширение Ninject Interception должно использовать подход с наименьшим общим знаменателем, поскольку оно разработано для поддержки нескольких прокси-библиотек.Если вы используете Castle напрямую, вы можете использовать перехватчики прокси-генераторов и селекторы-перехватчики для детального управления , что на самом деле является рекомендуемым подходом.Насколько я могу судить из исходного кода Ninject-DP2, это не поддерживается с расширением Ninject.

Лично у меня никогда не было большого успеха с расширением Ninject Interception именно по этой причине,и склонны использовать Castle DP2 напрямую.Однако, если вы делаете это в небольшом масштабе и не пишете приложение, чувствительное к производительности, у вас должно получиться хорошо писать динамические перехватчики.

...