C# 如何为Prism中的所有类添加跟踪拦截器?
我试图使用接口拦截器将跟踪拦截器添加到Prism应用程序的所有组件中。我几乎可以做到这一点,但是拦截器在声明事件的接口方面存在问题。是否有人在不需要属性的情况下成功实现了所有组件的aop跟踪 这是我的密码:C# 如何为Prism中的所有类添加跟踪拦截器?,c#,unity-container,prism,aop,C#,Unity Container,Prism,Aop,我试图使用接口拦截器将跟踪拦截器添加到Prism应用程序的所有组件中。我几乎可以做到这一点,但是拦截器在声明事件的接口方面存在问题。是否有人在不需要属性的情况下成功实现了所有组件的aop跟踪 这是我的密码: private void AddTracingInterceptor(Type from, IUnityContainer container) { container.AddNewExtension<Interception>(); if
private void AddTracingInterceptor(Type from, IUnityContainer container)
{
container.AddNewExtension<Interception>();
if (from.ToString().StartsWith("StockTraderRI")
&& !from.ToString().EndsWith("View")
&& from.IsInterface)
{
try
{
container.Configure<Interception>().SetInterceptorFor(from, new InterfaceInterceptor())
.AddPolicy("SomePolicy")
.AddMatchingRule(new AllMembersMatchingRule())
.AddCallHandler(new TraceCallHandler());
}
catch (Exception ex)
{
Debug.WriteLine("$$$" + from.ToString() + " " + ex.Message);
}
}
else
{
Debug.WriteLine("---" + from.ToString());
}
}
private void addtracinterceptor(输入from,IUnityContainer容器)
{
container.AddNewExtension();
if(from.ToString().StartsWith(“StockTraderRI”)
&&!from.ToString().EndsWith(“视图”)
&&from.i接口)
{
尝试
{
container.Configure()
.AddPolicy(“SomePolicy”)
.AddMatchingRule(新的AllMembersMatchingRule())
.AddCallHandler(新的TraceCallHandler());
}
捕获(例外情况除外)
{
Debug.WriteLine(“$$$”+from.ToString()+”+ex.Message);
}
}
其他的
{
Debug.WriteLine(“--”+from.ToString());
}
}
这是个例外:
内部异常
---------------
类型:System.TypeLoadException,mscorlib,版本=2.0.0.0,区域性=neutral,PublicKeyToken=b77a5c561934e089
消息:程序集“Unity\u ILEmit\u InterfaceProxies,Version=0.0.0,Culture=neutral,PublicKeyToken=null”中类型为“DynamicModule.ns.Wrapped\u IAccountPositionService\u 4c0175f8eca24b809f7a3875747d41c1”的方法“add\u Update”没有实现。
资料来源:mscorlib
帮助链接:
类型名称:DynamicModule.ns.Wrapped_IAccountPositionService_4c0175f8eca24b809f7a3875747d41c1
数据:System.Collections.ListDictionaryInternal
TargetSite:System.Type_TermCreateClass(Int32,System.Reflection.Module)
堆栈跟踪:位于System.Reflection.Emit.TypeBuilder.\u TermCreateClass(Int32句柄,模块)
在System.Reflection.Emit.TypeBuilder.CreateTypeNoLock()中
在System.Reflection.Emit.TypeBuilder.CreateType()处
在Microsoft.Practices.Unity.InterceptorExtension.InterfaceInterceptorClassGenerator.CreateProxyType()上
在Microsoft.Practices.Unity.InterceptionExtension.InterfaceInterceptor.CreateProxy(类型t,对象目标)
在Microsoft.Practices.Unity.InterceptionExtension.InstanceInterceptionStrategy.PostBuilding(IBuilderContext上下文)上
在Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext上下文)中,问题在于Unity InterceptionExtension中的InterfaceInterceptorClassGenerator,它绕过具有特殊名称的方法,并且不定义事件所需的添加和删除方法 我能看到的可能的解决办法是 1) 编辑Unity源代码并编写代码以定义事件IL代码。(见下文) 2) 将要拦截的接口中的所有事件更改为显式的Add和Remove委托方法(由真实事件实现)。INotifyPropertyChanged上的WPF绑定使得这对于Prism来说不切实际。 3) 放弃Unity,使用更好的IoC容器 你找到更好的解决问题的办法了吗 编辑:我现在坚持使用Unity 1.2,因此我最终修复了它,还不如发布代码,这也修复了派生接口的问题
private IEnumerable<MethodInfo> MethodsToIntercept()
{
return typeToIntercept.GetInterfaces()
.SelectMany(t => t.GetMethods())
.Union(typeToIntercept.GetMethods())
.Where(m => !m.IsSpecialName);
}
private IEnumerable<PropertyInfo> PropertiesToIntercept()
{
return typeToIntercept.GetInterfaces()
.SelectMany(t => t.GetProperties())
.Union(typeToIntercept.GetProperties());
}
private IEnumerable<EventInfo> EventsToIntercept()
{
return typeToIntercept.GetInterfaces()
.SelectMany(t => t.GetEvents())
.Union(typeToIntercept.GetEvents());
}
您需要修改Unity.Extensions.InterceptorClassGenerator中的InterfaceInterceptorClassGenerator类,首先添加CreateProxyType
public Type CreateProxyType()
{
int memberCount = 0;
foreach (MethodInfo method in MethodsToIntercept())
{
OverrideMethod(method, memberCount++);
}
foreach (PropertyInfo property in PropertiesToIntercept())
{
OverrideProperty(property, memberCount++);
}
// Add this
foreach (EventInfo evt in EventsToIntercept())
{
AddEvent(evt);
}
// -- SNIP --
}
修改内容以获得“基本”接口的方法
private IEnumerable<MethodInfo> MethodsToIntercept()
{
return typeToIntercept.GetInterfaces()
.SelectMany(t => t.GetMethods())
.Union(typeToIntercept.GetMethods())
.Where(m => !m.IsSpecialName);
}
private IEnumerable<PropertyInfo> PropertiesToIntercept()
{
return typeToIntercept.GetInterfaces()
.SelectMany(t => t.GetProperties())
.Union(typeToIntercept.GetProperties());
}
private IEnumerable<EventInfo> EventsToIntercept()
{
return typeToIntercept.GetInterfaces()
.SelectMany(t => t.GetEvents())
.Union(typeToIntercept.GetEvents());
}
如果在接口中有索引器,您可能还需要对其执行类似的操作,但只需修改接口即可轻松地获取/设置方法