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

tom*_*ich 3 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"))
                )
        );
Run Code Online (Sandbox Code Playgroud)

当我去使用WCF测试客户端来检查时,似乎每个服务下可用的方法都是该服务和我之前所有服务的组合.例: 查看WCF测试客户端中的服务

我做错了吗?你不能WcfFacility多次添加,并在互联网上四处寻找,我似乎无法找到一个人在一个设施中托管多个服务的例子.

有任何想法吗?

tom*_*ich 9

我已经明白了.以前,我使用以下代码在MetaData上启用HttpGet:

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

这是遵循这个github示例中的代码.

似乎这种方法会导致WcfFacility在任何get请求中为所有服务共享MetaData.

解决方案很简单.首先,删除那些东西.其次,以这种方式配置每个服务组件

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")
        )                               
),
Run Code Online (Sandbox Code Playgroud)

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

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

预期的行为! 好极了!

编辑:一旦我开始工作,我去工作去除可能需要或不需要的东西 - 我喜欢约会而不是配置.这是结果,似乎没有任何其他东西可以带走.关于这一点的好处是我可以进一步重构所有服务的通用注册,而不是每个服务都需要注册一个.只是分享货物.

        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")
                    )
        ),
Run Code Online (Sandbox Code Playgroud)

这是通用注册.

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")                       
            )
        )
)
Run Code Online (Sandbox Code Playgroud)