Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何为Prism中的所有类添加跟踪拦截器?_C#_Unity Container_Prism_Aop - Fatal编程技术网

C# 如何为Prism中的所有类添加跟踪拦截器?

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

我试图使用接口拦截器将跟踪拦截器添加到Prism应用程序的所有组件中。我几乎可以做到这一点,但是拦截器在声明事件的接口方面存在问题。是否有人在不需要属性的情况下成功实现了所有组件的aop跟踪

这是我的密码:

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());
    }
如果在接口中有索引器,您可能还需要对其执行类似的操作,但只需修改接口即可轻松地获取/设置方法