我如何获得Ninject.Extensions.Interception,基本上让我将特定的拦截器绑定到任何具有属性的方法。。。psudocode:
Kernel.Intercept(context => context.Binding.HasAttribute<TransactionAttribute>())
.With<TransactionInterceptor>
具有类似的类
public SomeClass
{
[TransactionAttribute]
public void SomeTransactedMethod()
{ /*do stuff */ }
}
假设您使用的是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();
更新
你可以创建一个自定义的计划策略。
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();
以下是我用于相同目的的代码
//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
}