WCF服务无法使用Unity 2.0拦截进行拦截

WCF服务无法使用Unity 2.0拦截进行拦截,wcf,unity-container,aop,Wcf,Unity Container,Aop,在我的WCF web应用程序中,我配置了Unity容器进行拦截。下面是我的unity配置 <unity xmlns="http://schemas.microsoft.com/practices/2010/unity"> <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Mic

在我的WCF web应用程序中,我配置了Unity容器进行拦截。下面是我的unity配置

<unity xmlns="http://schemas.microsoft.com/practices/2010/unity"> 
    <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration"/>

    <assembly name="Infrastructure" />
    <assembly name="WCFServiceLib1"/>

    <namespace name="Infrastructure"/>
    <namespace name="WCFServiceLib1" />

    <container>
      <extension type="Interception" />
      <register type="IService1" mapTo="Service1">
        <interceptor type="InterfaceInterceptor"/>
        <interceptionBehavior type="LogPerformanceDataBehavior"/>
      </register>
    </container>
</unity>

当我尝试使用wcftestclient工具调用服务上的方法时,会引发以下异常

ArgumentException-类型WCFServiceLib1.Service1不可拦截。
参数名称:interceptedType

我使用svctraceviewer工具获取上述异常详细信息

下面是LogPerformanceDataBehavior类的实现

public class LogPerformanceDataBehavior : IInterceptionBehavior
{
    public IEnumerable<Type> GetRequiredInterfaces()
    {
        return Type.EmptyTypes;
    }

    public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
    {
        var watch = new Stopwatch();

        watch.Start();
        IMethodReturn methodReturn = getNext()(input, getNext);
        watch.Stop();

        string sb = string.Format("Method {0}.{1} executed in: ({2} ms, {3} ticks){4}",
                                  input.MethodBase.DeclaringType.Name, input.MethodBase.Name,
                                  watch.ElapsedMilliseconds, watch.ElapsedTicks, Environment.NewLine);

        using (StreamWriter outfile = new StreamWriter(@"c:\logs\Performance.txt"))
        {
            outfile.Write(sb);
        }

        return methodReturn;
    }

    public bool WillExecute
    {
        get { return true; }
    }
}
公共类LogPerformanceDataBehavior:IInterceptionBehavior
{
public IEnumerable GetRequiredInterface()
{
return Type.EmptyTypes;
}
公共IMethodReturn调用(IMethodInvoke输入,GetNextInterceptionBehaviorDelegate getNext)
{
var watch=新秒表();
watch.Start();
IMethodReturn methodReturn=getNext()(输入,getNext);
看,停;
string sb=string.Format(“方法{0}.{1}在:({2}ms,{3}ticks){4}中执行”,
input.MethodBase.DeclaringType.Name,input.MethodBase.Name,
watch.elapsedMills、watch.ElapsedTicks、Environment.NewLine);
使用(StreamWriter outfile=newstreamwriter(@“c:\logs\Performance.txt”))
{
写(某人);
}
返回方法返回;
}
公共场所将被执行
{
获取{return true;}
}
}


可能有什么问题?

问题在于WCF实例提供程序没有解析接口。它正在解析服务类型。您使用的是接口拦截器,它不能直接应用于类。看

解决办法是:

  • 更改为
    虚拟方法Interceptor
  • 将要拦截的任何服务方法标记为
    virtual
  • 注册示例:

    <register type="Service1" >         
        <interceptor type="VirtualMethodInterceptor"/> 
        <interceptionBehavior type="LogPerformanceDataBehavior"/>       
    </register>
    

    问题在于WCF实例提供程序没有解析接口。它正在解析服务类型。您使用的是接口拦截器,它不能直接应用于类。看

    解决办法是:

  • 更改为
    虚拟方法Interceptor
  • 将要拦截的任何服务方法标记为
    virtual
  • 注册示例:

    <register type="Service1" >         
        <interceptor type="VirtualMethodInterceptor"/> 
        <interceptionBehavior type="LogPerformanceDataBehavior"/>       
    </register>
    
    
    
    您是否尝试拦截您的服务或客户端代理?WCF有自己的基础设施来拦截对服务的呼叫。我认为这不适合任何其他拦截机制(无论是Unity还是其他)。如果你想监控WCF的性能,你应该看看@SebastianWeber,我正试图拦截对服务上任何方法的调用。我使用了本文中的步骤来为服务配置unity。我知道UnityServiceHost/Factory/InstanceProvider,但我不确定在这种情况下使用unity的拦截机制是否是一个好主意(甚至是可能的)。WCF有一个调用处理程序管道,该管道从在线拾取对服务的调用开始,验证它们,授权、记录等等。如果你只是对性能测量感兴趣,我会坚持使用WCF内置的性能计数器。它们是经过验证的,快速且有很好的文档记录。如果您想将拦截用于其他用途:请查看WCF基础设施为您提供了什么。它是为扩展性而构建的。您是否尝试拦截您的服务或客户端代理?WCF有自己的基础设施来拦截对服务的呼叫。我认为这不适合任何其他拦截机制(无论是Unity还是其他)。如果你想监控WCF的性能,你应该看看@SebastianWeber,我正试图拦截对服务上任何方法的调用。我使用了本文中的步骤来为服务配置unity。我知道UnityServiceHost/Factory/InstanceProvider,但我不确定在这种情况下使用unity的拦截机制是否是一个好主意(甚至是可能的)。WCF有一个调用处理程序管道,该管道从在线拾取对服务的调用开始,验证它们,授权、记录等等。如果你只是对性能测量感兴趣,我会坚持使用WCF内置的性能计数器。它们是经过验证的,快速且有很好的文档记录。如果您想将截取用于其他用途:看看WCF基础结构为您提供了什么。它是为可扩展性而构建的。或者您可以从MarshalByRefObject继承并使用TransparentProxyInterceptor或修改WCF实例提供程序以通过接口进行解析。如果您只是在执行IInstanceProvider,则尝试解析接口不起作用。我试过了。WCF需要一个类实例,如果您给它其他任何东西,它将开始抛出异常。从技术上讲,MarshallByRefObject是一个选项,但它是用于.NET远程处理的。让WCF服务类从.NET远程处理继承对我来说是个坏主意。。。尽管无可否认,我没有明确的专业知识。或者您可以从MarshalByRefObject继承并使用TransparentProxyInterceptor或修改WCF实例提供程序以按接口解析。如果您只是在做IInstanceProvider,那么尝试解析接口是行不通的。我试过了。WCF需要一个类实例,如果您给它其他任何东西,它将开始抛出异常。从技术上讲,MarshallByRefObject是一个选项,但它是用于.NET远程处理的。让WCF服务类从.NET远程处理继承对我来说是个坏主意。。。虽然我承认我没有专业知识来明确地说。