0

我一直在网上搜索我遇到的问题的解决方案。我无法连接我的 WCF 服务(托管 IIS)以进行拦截 - 我可以为我指定的所有其他类/接口这样做。

我的代码如下:

报告服务.svc

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

报告服务.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>()

该服务运行良好,但显然没有拦截。

我看过维基,但没有快乐。

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

4

1 回答 1

1

WCF 内部有一些“魔法”,如果您告诉服务主机您所托管的具体类型的名称,它希望您始终只托管该具体类型。

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

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

解决方案是告诉 Autofac 要托管的接口类型而不是具体类型。(这是Autofac WCF 集成 wiki 页面上的“合同类型注册” 。)然后使用接口拦截器注册事物并将接口用作公开服务。

那么,在您的 .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 获取要托管的具体类型时,它将获取动态代理类型而不是基本/拦截的具体类型,并且您不应该收到运行时绑定错误。

于 2013-11-11T22:01:28.407 回答