我一直在网上搜索解决我遇到的问题的方法。我无法连接我的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,但我没有快乐。
关于我做错了什么的想法?
答案 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获取托管的具体类型时,它将获得动态代理类型而不是基本/截获的具体类型,并且您不应该获得运行时绑定错误。