2011-06-17 73 views
13

我怎樣才能得到Ninject.Extensions.Interception基本上讓我結合特定攔截到具有屬性... psudocode任何方法:Ninject攔截具有某些屬性的任何方法?

Kernel.Intercept(context => context.Binding.HasAttribute<TransactionAttribute>()) 
     .With<TransactionInterceptor> 

有了這樣一個類:

public SomeClass 
{ 
    [TransactionAttribute] 
    public void SomeTransactedMethod() 
    { /*do stuff */ } 
} 

回答

13

假設你正在使用Ninject.Extensions.Interception這應該做的伎倆

public class TransactionInterceptor : IInterceptor 
{ 
    public void Intercept(IInvocation invocation) 
    { 
     // Do something... 
    } 
} 

public class TransactionAttribute : InterceptAttribute 
{ 
    public override IInterceptor CreateInterceptor(IProxyRequest request) 
    { 
     return new TransactionInterceptor(); 
    } 
} 

public class SomeClass 
{ 
    [Transaction] 
    public virtual void SomeTransactedMethod() { } 
} 

確保應該被攔截的方法是記號編輯爲虛擬。

當調用SomeTransactedMethod()時,應該攔截它。

var kernel = new StandardKernel(); 
kernel.Bind<SomeClass>().ToSelf(); 

var someClass = kernel.Get<SomeClass>(); 
someClass.SomeTransactedMethod(); 

UPDATE

您可以創建一個自定義的規劃策略。

public class CustomPlanningStrategy<TAttribute, TInterceptor> : 
    NinjectComponent, IPlanningStrategy 
     where TAttribute : Attribute 
     where TInterceptor : IInterceptor 
{ 
    private readonly IAdviceFactory adviceFactory; 
    private readonly IAdviceRegistry adviceRegistry; 

    public CustomPlanningStrategy(
     IAdviceFactory adviceFactory, IAdviceRegistry adviceRegistry) 
     { 
      this.adviceFactory = adviceFactory; 
      this.adviceRegistry = adviceRegistry; 
     } 

     public void Execute(IPlan plan) 
     { 
      var methods = GetCandidateMethods(plan.Type); 
      foreach (var method in methods) 
      { 
       var attributes = method.GetCustomAttributes(
        typeof(TAttribute), true) as TAttribute[]; 
       if (attributes.Length == 0) 
       { 
        continue; 
       } 

       var advice = adviceFactory.Create(method); 

       advice.Callback = request => request.Kernel.Get<TInterceptor>(); 
       adviceRegistry.Register(advice); 

       if (!plan.Has<ProxyDirective>()) 
       { 
        plan.Add(new ProxyDirective()); 
       } 
      } 
     } 
    } 

    private static IEnumerable<MethodInfo> GetCandidateMethods(Type type) 
    { 
     var methods = type.GetMethods(
      BindingFlags.Public | 
      BindingFlags.NonPublic | 
      BindingFlags.Instance 
     ); 

     return methods.Where(ShouldIntercept); 
    } 

    private static bool ShouldIntercept(MethodInfo methodInfo) 
    { 
     return methodInfo.DeclaringType != typeof(object) && 
       !methodInfo.IsPrivate && 
       !methodInfo.IsFinal; 
    } 
} 

這應該現在工作。

var kernel = new StandardKernel(); 
kernel.Components.Add<IPlanningStrategy, 
    CustomPlanningStrategy<TransactionAttribute, TransactionInterceptor>>(); 

kernel.Bind<SomeClass>().ToSelf(); 

var someClass = kernel.Get<SomeClass>(); 
someClass.SomeTransactedMethod(); 
+0

不能有我的屬性從InterceptAttribute繼承代碼,作爲交易的域名ion屬性被定義爲沒有關於DI關注的知識......這就是爲什麼我需要通過在應用程序層內定義的Kernel.Intercept方法來實現它。 – somemvcperson 2011-06-17 23:39:32

2

這裏是我用於相同目的

//Code in Bind Module 
this.Bind(typeof(ServiceBase<,>)) 
    .ToSelf() 
    .InRequestScope() 
    .Intercept() 
    .With<TransactionInterceptor>(); 

而且

public class TransactionInterceptor : IInterceptor 
{ 
    #region Constants and Fields 

    public ISession session; 
    private ISessionFactory sessionFactory; 

    #endregion 

    #region Constructors and Destructors 

    public TransactionInterceptor(ISession session, ISessionFactory sessionFactory) 
    { 
     this.sessionFactory = sessionFactory; 
     this.session = session; 
    } 


    #endregion 

    public void Intercept(IInvocation invocation) 
    { 
     try 
     { 
      if (!session.IsConnected) 
       session = sessionFactory.OpenSession(); 

      session.BeginTransaction(); 
      invocation.Proceed(); 
      if (this.session == null) 
      { 
       return; 
      } 

      if (!this.session.Transaction.IsActive) 
      { 
       return; 
      } 
      else 
      { 
       this.session.Transaction.Commit(); 
      } 
     } 
     catch (Exception) 
     { 
      if (this.session == null) 
      { 
       return; 
      } 

      if (!this.session.Transaction.IsActive) 
      { 
       return; 
      } 

      this.session.Transaction.Rollback(); 

      throw; 
     } 
    } 
} 

和代碼TransactionAttribute

public class TransactionAttribute : InterceptAttribute 
{ 
    #region Public Methods 

    public override IInterceptor CreateInterceptor(IProxyRequest request) 
    { 
     return request.Context.Kernel.Get<TransactionInterceptor>() ; 
    } 

    #endregion 
}