как использовать перехват Ninject с помощью InterceptAttribute

У меня есть NinjectWebCommon следующим образом. Я не могу заставить TimingInterceptor запускать метод с установленным атрибутом Timing. Он отлично работает, если перехватчик определен на уровне класса, где будут перехватываться все вызовы методов, но я хотел бы иметь возможность указать метод, который я хочу перехватить (согласиться).

У меня добавлен Ninject.Extensions.Interception.DynamicProxy.

public static class NinjectWebCommon 
{
    private static readonly Bootstrapper bootstrapper = new Bootstrapper();

    /// <summary>
    /// Starts the application
    /// </summary>
    public static void Start() 
    {
        DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
        DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
        bootstrapper.Initialize(CreateKernel);
    }

    /// <summary>
    /// Stops the application.
    /// </summary>
    public static void Stop()
    {
        bootstrapper.ShutDown();
    }

    /// <summary>
    /// Creates the kernel that will manage your application.
    /// </summary>
    /// <returns>The created kernel.</returns>
    private static IKernel CreateKernel()
    {
        var NinjectSettings = new NinjectSettings();
        var kernel = new StandardKernel(NinjectSettings);

        kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
        kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

        GlobalConfiguration.Configuration.DependencyResolver = new BazingaNinjectResolver(kernel);

        RegisterServices(kernel);
        return kernel;
    }

    /// <summary>
    /// Load your modules or register your services here!
    /// </summary>
    /// <param name="kernel">The kernel.</param>
    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<IMyService>().To<MyService>().InRequestScope();
    }        
}

мой класс обслуживания определяется следующим образом

public class MyService : IMyService
{
    Logger log;

    public MyService()
    {
        log = LogManager.GetLogger(this.GetType().FullName);
    }

    [Timing]
    public string GetString()
    {
        log.Info("log me!!");
        return "Cool string !!!!";
    }

    public string GetUnInterceptString()
    {
        return "Not intercepted";
    }
}

Перехватчик и атрибут определяются следующим образом

public class TimingAttribute : InterceptAttribute
{
    public override IInterceptor CreateInterceptor(IProxyRequest request)
    {
        return request.Context.Kernel.Get<TimingInterceptor>();
    }
}

public class TimingInterceptor : SimpleInterceptor
{
    readonly Stopwatch _stopwatch = new Stopwatch();

    protected override void BeforeInvoke(IInvocation invocation)
    {
        _stopwatch.Start();
    }

    protected override void AfterInvoke(IInvocation invocation)
    {
        _stopwatch.Stop();
        string message = string.Format("Execution of {0} took {1}.",
            invocation.Request.Method,
            _stopwatch.Elapsed);

        _stopwatch.Reset();
    }
}

person Eatdoku    schedule 19.03.2013    source источник


Ответы (1)


Вам нужно, чтобы он был виртуальным, чтобы ninject мог его перехватить:

public class MyService : IMyService
{
    Logger log;

    public MyService()
    {
        log = LogManager.GetLogger(this.GetType().FullName);
    }

    [Timing]
    public virtual string GetString()
    {
        log.Info("log me!!");
        return "Cool string !!!!";
    }

    public string GetUnInterceptString()
    {
        return "Not intercepted";
    }
}
person Adam Bell    schedule 19.03.2013
comment
верно, я вспомнил, что где-то упоминал об этом, теперь это работает, спасибо - person Eatdoku; 19.03.2013
comment
можно ли перехватить частные методы с помощью атрибута? - person Eatdoku; 19.03.2013
comment
Не с ninject, вам понадобится postsharp или какая-то другая магия АОП. - person Adam Bell; 19.03.2013