wcf - 如何使用一个 WcfFacility 托管多个服务

标签 wcf castle-windsor wcffacility

我尝试使用一个 WcfFacility 和 IIS 托管多个服务,但看到一些令人困惑的结果。

这是我的配置:

        var baseUri = new Uri(HttpContext.Current.Request.Url.GetComponents(UriComponents.SchemeAndServer, UriFormat.Unescaped));

        container.AddFacility<WcfFacility>(f => { f.CloseTimeout = TimeSpan.Zero; }).Register(
            Component.For<IAttributeService>()                  
                .ImplementedBy<AttributeService>()
                .AsWcfService(
                    new DefaultServiceModel()
                        .Hosted()                           
                        .AddEndpoints(
                            WcfEndpoint.ForContract<IAttributeService>().BoundTo(new BasicHttpBinding()).At("Soap11"),
                            WcfEndpoint.ForContract<IAttributeService>().BoundTo(new WSHttpBinding()).At("Soap12")
                        )
                .AddBaseAddresses(new Uri(baseUri, "AttributeService.svc"))                 
                ),                      
            Component.For<ISessionService>()
                .ImplementedBy<SessionService>()
                .AsWcfService(
                    new DefaultServiceModel()
                        .Hosted()                           
                        .AddEndpoints(
                            WcfEndpoint.ForContract<ISessionService>().BoundTo(new BasicHttpBinding()).At("Soap11"),
                            WcfEndpoint.ForContract<ISessionService>().BoundTo(new WSHttpBinding()).At("Soap12")
                        )
                .AddBaseAddresses(new Uri(baseUri, "SessionService.svc"))
                ),          
            Component.For<ISampleService>()
                .ImplementedBy<SampleService>()
                .AsWcfService(
                    new DefaultServiceModel()
                        .Hosted()
                        .AddEndpoints(
                            WcfEndpoint.ForContract<ISampleService>().BoundTo(new BasicHttpBinding()).At("Soap11"),
                            WcfEndpoint.ForContract<ISampleService>().BoundTo(new WSHttpBinding()).At("Soap12")
                        )
                .AddBaseAddresses(new Uri(baseUri, "SampleService.svc"))
                )
        );

当我使用 WCF 测试客户端来检查这一点时,似乎每个服务下可用的方法都是该服务和我之前混合的所有服务的组合。例子: looking at a service in WCF Test Client

我这样做错了吗?您无法多次添加 WcfFacility,并且在互联网上查找,我似乎找不到有人在一个设施中托管多个服务的示例。

有什么想法吗?

最佳答案

我已经弄清楚了。以前,我使用以下代码在元数据上启用 HttpGet:

var metadata = new ServiceMetadataBehavior { HttpGetEnabled = true };
container.Register(Component.For<IServiceBehavior>().Instance(metadata));

遵循 this github example 中的代码.

似乎这种方法会导致 WcfFacility 在任何获取请求上共享所有服务的元数据。

解决方案很简单。首先,删除那些东西。二、按照这样的方式配置各个服务组件

Component.For<IAttributeService>()                  
.ImplementedBy<AttributeService>()
.AsWcfService(
    new DefaultServiceModel()
        .Hosted()
        .PublishMetadata(x => x.EnableHttpGet())
        .AddBaseAddresses(new Uri(baseUri, "AttributeService.svc"))             
        .AddEndpoints(
            WcfEndpoint.ForContract<IAttributeService>().BoundTo(new BasicHttpBinding()).At("Soap11"),
            WcfEndpoint.ForContract<IAttributeService>().BoundTo(new WSHttpBinding()).At("Soap12")
        )                               
),

具体来说,技巧是在每个组件中添加此代码.PublishMetadata(x => x.EnableHttpGet())

现在我看到了每项服务的预期行为。

The expected behavior! Yay!

编辑:一旦我开始工作,我就开始删除可能需要或不需要的东西 - 我喜欢约定优于配置。这是结果,似乎没有什么可带走的。这样做的好处是,我可以进一步重构为所有服务的通用注册,而不是需要为每个服务进行一次注册。只是分享商品。

        Component.For<IAttributeService>()
            .ImplementedBy<AttributeService>()
            .AsWcfService(
                new DefaultServiceModel()
                    .Hosted()
                    .PublishMetadata(x => x.EnableHttpGet())
                    .AddEndpoints(
                        WcfEndpoint.BoundTo(new BasicHttpBinding()).At("Soap11"),
                        WcfEndpoint.BoundTo(new WSHttpBinding()).At("Soap12")
                    )
        ),

这是通用注册。

Classes.FromThisAssembly()
.Where(t => Attribute.IsDefined(t, typeof(StandardServiceAttribute)))
.WithService.Select((t, _) => t.GetInterfaces().Where(i => Attribute.IsDefined(i, typeof(ServiceContractAttribute),false)))
.Configure
(cr => 
    cr.AsWcfService(
        new DefaultServiceModel()
            .Hosted()
            .PublishMetadata(x => x.EnableHttpGet())
            .AddEndpoints(
                WcfEndpoint.BoundTo(new BasicHttpBinding()).At("Soap11"),
                WcfEndpoint.BoundTo(new WSHttpBinding()).At("Soap12")                       
            )
        )
)

关于wcf - 如何使用一个 WcfFacility 托管多个服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9739668/

相关文章:

wcf - CaSTLe WCF 设施,对非通用合约使用通用接口(interface)

wcf - 温莎城堡 WcfFacility 错误。忘记注册组件?

wcf - 在 CaSTLe.Windsor 中将客户端基于任务的操作与 WCFFacility 结合使用

c# - Azure 服务总线托管 REST 服务

c# - CaSTLe温莎代码设计问题

dependency-injection - 如何在多项目解决方案中使用 .net 核心依赖注入(inject)?

c# - 为 SOA Web 应用程序托管 WCF 服务的最佳方式

wcf - SAML 断言消费者服务 (ACS) - 实现建议

c# - 如何在 C# 中通过代码设置 ServiceHostingEnvironmentSection.AspNetCompatibilityEnabled

jquery - 如何从 jquery/ajax 向 [OperationContract] webservice 方法传递参数?