Cor*_*ndt 5 aop ninject interceptor ninject-extensions ninject-interception
我会形容我的环境:我有Ninject + Ninject拦截扩展合作,以使所有的方法,标有特殊属性的拦截器自动注册.这是一个常见的AoP +属性+ DI容器场景.
我的问题是:当移植到Ninject和Ninject拦截扩展的最新版本 - 3.0我开始变得异常时,我的拦截器应该运行.我的InterceptorRegistrationStrategy在解析属性类型和注册拦截器时工作正常.但运行截获的方法会导致以下异常:
System.ArgumentException : Interface not found.
at System.RuntimeTypeHandle.VerifyInterfaceIsImplemented(RuntimeTypeHandle handle, RuntimeTypeHandle interfaceHandle)
at System.RuntimeType.GetInterfaceMap(Type ifaceType)
at Ninject.Extensions.Interception.Advice.Advice.MatchesMethod(IProxyRequest request)
at System.Linq.Enumerable.WhereListIterator`1.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList(IEnumerable`1 source)
at Ninject.Extensions.Interception.Registry.AdviceRegistry.GetInterceptorsForRequest(IProxyRequest request)
at Ninject.Extensions.Interception.Registry.AdviceRegistry.GetInterceptors(IProxyRequest request)
at Ninject.Extensions.Interception.Wrapper.StandardWrapper.CreateInvocation(IProxyRequest request)
at Ninject.Extensions.Interception.Wrapper.DynamicProxyWrapper.Intercept(IInvocation castleInvocation)
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Infrastructure.Tests.Persistance.Conversations.NinjectConversationInterceptorBehavior.ShouldCreateInterceptorOnImplicitConversation() in NinjectConversationInterceptorBehavior.cs: line 74
Run Code Online (Sandbox Code Playgroud)
我有点左诉诸反射器,并使用Ninject拦截扩展来源做些什么这个问题,没有足够的文档,它让我在一个糟糕的位置配对.
移植到Ninject 3.0时,任何人都有同样的例外吗?
这是我用来根据属性自动注册拦截器的代码:
public class NinjectConversationInterceptorRegistrationStrategy : InterceptorRegistrationStrategy
{
public NinjectConversationInterceptorRegistrationStrategy(IAdviceFactory adviceFactory,
IAdviceRegistry adviceRegistry)
: base(adviceFactory, adviceRegistry)
{
}
public override void Execute(IPlan plan)
{
var pcAttribute = plan.Type.GetOneAttribute<PersistenceConversationalAttribute>();
if (pcAttribute != null)
{
if (pcAttribute.MethodsIncludeMode == MethodsIncludeMode.Implicit)
{
foreach (var mi in GetCandidateMethods(plan.Type))
{
RegisterMethodInterceptors(plan.Type, mi);
if (!plan.Has<ProxyDirective>())
{
plan.Add(new ProxyDirective());
}
}
}
else
{
foreach (
var mi in
GetCandidateMethods(plan.Type).Where(
mi => mi.HasAttribute<PersistenceConversationAttribute>()))
{
if (!mi.IsVirtual)
{
throw new InvalidOperationException(
string.Format("[PersistentCoversation] attribute used on non-virtual method {0}.{1}",
mi.DeclaringType.Name,
mi.Name));
}
RegisterMethodInterceptors(plan.Type, mi);
if (!plan.Has<ProxyDirective>())
{
plan.Add(new ProxyDirective());
}
}
}
}
}
protected virtual void RegisterMethodInterceptors(Type type, MethodInfo method)
{
IAdvice advice = this.AdviceFactory.Create(method);
advice.Callback = GetIntercepor;
this.AdviceRegistry.Register(advice);
}
protected virtual IInterceptor GetIntercepor(IProxyRequest arg)
{
var interceptor = new NinjectConversationLazyInterceptor(arg.Kernel);
return interceptor;
}
protected override bool ShouldIntercept(MethodInfo methodInfo)
{
if (IsPropertySetter(methodInfo))
{
return false;
}
var ret = base.ShouldIntercept(methodInfo);
return ret;
}
private static bool IsPropertySetter(MethodBase methodInfo)
{
return methodInfo.IsSpecialName && methodInfo.Name.StartsWith("set_");
}
}
Run Code Online (Sandbox Code Playgroud)
拦截的行为发生了变化:当注入接口时,扩展将创建接口代理而不是类代理,因为这样做的优点是方法不再需要是虚拟的。要么你必须把它放到接口中,将该方法排除在拦截之外(拦截无论如何都无法调用的方法是没有用的)或者注入一个类而不是接口
归档时间: |
|
查看次数: |
811 次 |
最近记录: |