2013-03-19 18 views
5

verwenden Ich habe ein NinjectWebCommon wie folgt. Ich kann den TimingInterceptor nicht auf die Methode anwenden, für die das Attribut "Timing" festgelegt ist. Es funktioniert gut, wenn der Intercontor auf der Klassenebene definiert ist, auf der alle Methodenaufrufe abgefangen werden, aber ich hätte gerne die Möglichkeit, die Methode anzugeben, die ich abfangen möchte (Opt-In).wie Ninject intercept mit InterceptAttribute

Ich habe die Ninject.Extensions.Interception.DynamicProxy hinzugefügt.

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(); 
    }   
} 

meine Service-Klasse definieren, wie folgt

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"; 
    } 
} 

Interceptor und Attribut wie folgt definieren

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(); 
    } 
} 

Antwort

3

Sie müssen es virtuell sein, denn ninject es abfangen:

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"; 
    } 
} 
+0

richtig, ich erinnerte mich, es irgendwo erwähnt zu sehen, es funktioniert jetzt dank – Eatdoku

+0

ist es möglich, private Methoden mit Attribut abzufangen? – Eatdoku

+2

Nicht mit Ninject, würden Sie Postsharp oder eine andere AOP Magie –