【问题标题】:WCF service not interceptable using Unity 2.0 InterceptionWCF 服务无法使用 Unity 2.0 拦截进行拦截
【发布时间】:2013-11-28 15:50:55
【问题描述】:

在我的 WCF Web 应用程序中,我为拦截配置了 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; }
    }
}


可能有什么问题?

【问题讨论】:

  • 您是否尝试拦截您的服务客户端代理? WCF 有自己的基础设施来拦截对服务的调用。我认为这不适用于任何其他拦截机制(无论是 Unity 还是其他)。如果你想监控 WCF 的性能,你应该看看WCF performance counters
  • @SebastianWeber 我正在尝试拦截对服务上任何方法的调用。我已经使用link 中的步骤为服务配置了统一性。
  • 我知道 UnityServiceHost/Factory/InstanceProvider 但我不确定在这种情况下使用 Unity 的拦截机制是否是一个好主意(甚至可能)。WCF 有一个调用处理程序管道从选择对服务的调用开始,验证它们,授权它们,记录它们等等。如果你只是对性能测量感兴趣,我会坚持使用 WCF 内置的性能计数器。它们经过验证、快速且有据可查.如果您想将拦截用于其他用途:看看 WCF 基础结构为您提供了什么。它是为可扩展性而构建的。

标签: wcf unity-container aop


【解决方案1】:

问题在于 WCF 实例提供程序没有解析接口。它解决了服务类型。您正在使用接口拦截器,它不能直接应用于类。见Comparison of Interception Techniques

解决方法是:

  1. 更改为VirtualMethodInterceptor
  2. 将任何要拦截的服务方法标记为virtual

注册示例:

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

【讨论】:

  • 或者您可以从 MarshalByRefObject 继承并使用 TransparentProxyInterceptor 或修改 WCF 实例提供程序以通过接口解析。
  • 如果您只是在做 IInstanceProvider,那么尝试解析接口是行不通的。我尝试过这个。 WCF 想要一个类实例,如果你给它其他任何东西,它就会开始抛出异常。从技术上讲,MarshalByRefObject 是一个选项,但它适用于 .NET Remoting。从 .NET 远程处理继承 WCF 服务类对我来说似乎是个坏主意......尽管我承认我没有专业知识来明确地说。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多