Autofac - 无法让Interceptor在服务上工作

时间:2013-11-11 04:36:57

标签: c# wcf autofac

我一直在网上搜索解决我遇到的问题的方法。我无法连接我的WCF服务(IIS托管)进行拦截 - 我能够为我指定的所有其他类/接口执行此操作。

我的代码如下:

ReportingService.svc

 <%@ ServiceHost Language="C#" Debug="true" Service="myNameSpace.ReportingService, myNameSpace" Factory="Autofac.Integration.Wcf.AutofacServiceHostFactory, Autofac.Integration.Wcf" %>

ReportingService.cs

namespace myNameSpace
{
  public class ReportingService : IReportingService
  {
      public ReportingService()
      {
      }

      public virtual ReportResponse GetReport(ReportRequest request)
      {
        //Arbitrary code
      }
  }
}

容器初始化

[assembly: WebActivator.PreApplicationStartMethod(typeof(myNameSpace.App_Start.AutofacInitialization), "Start")]

namespace myNameSpace.App_Start
{
    //using's removed to save space

    public static class AutofacInitialization
    {
        public static void Start()
        {
            var builder = new ContainerBuilder();
            builder.Register(x => new AuditInterceptor());

            //Working - Context registered and interception working as expected
            builder.RegisterType<ReportContext>().As<IReportContext>.EnableClassInterceptors().InterceptedBy(typeof(AuditInterceptor));

            //Fails - The following causes a runtime exception of "The client and service bindings may be mismatched."
            builder.RegisterType<ReportingService>().EnableClassInterceptors().InterceptedBy(typeof(AuditInterceptor));

            AutofacServiceHostFactory.Container = builder.Build();
        }
    }
}

如上所述,在ReportingService上启用拦截时,我收到运行时异常。如果我删除拦截并只使用

builder.RegisterType<ReportingService>()

服务运行正常,但显然没有拦截。

我看过wiki,但我没有快乐。

关于我做错了什么的想法?

1 个答案:

答案 0 :(得分:1)

在WCF中有一些“魔力”,如果你告诉服务主机你正在托管的具体类型的名称,它希望你总是只托管那种具体类型。

使用类拦截器,Castle.DynamicProxy2生成一个具有相同签名和具体内容的新类型,但是当您尝试解析具体类型时,您将获得动态代理类型。

由于这与原始具体类型不完全相同,因此WCF爆炸。我在使用Autofac支持多租户服务托管时遇到了这个问题。

解决方案是告诉Autofac interface 类型是主机而不是具体类型。 (这是"Contract Type Registration" on the Autofac WCF integration wiki page。)然后注册事物using interface interceptors并将接口用作公开的服务。

在你的.svc文件中,它将是:

<%@ ServiceHost
  Language="C#"
  Debug="true"
  Service="myNameSpace.IReportingService, myNameSpace"
  Factory="Autofac.Integration.Wcf.AutofacServiceHostFactory, Autofac.Integration.Wcf" %>

服务类型的注册如下:

builder.RegisterType<ReportingService>()
  .As<IReportingService>()
  .EnableInterfaceInterceptors()
  .InterceptedBy(typeof(AuditInterceptor));

现在,当WCF获取托管的具体类型时,它将获得动态代理类型而不是基本/截获的具体类型,并且您不应该获得运行时绑定错误。

相关问题