Как разместить несколько сервисов, используя один WcfFacility - PullRequest
3 голосов
/ 16 марта 2012

Я пытаюсь разместить несколько служб, используя один 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 несколько раз, и, покопавшись в интернете, я не могу найти пример, когда кто-то размещает несколько служб в одном учреждении.

Есть идеи?

1 Ответ

8 голосов
/ 16 марта 2012

Я понял это. Ранее я включал HttpGet в MetaData, используя следующий код:

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

Который следовал за кодом в этом примере с github .

Кажется, что этот подход заставляет WcfFacility совместно использовать метаданные для всех сервисов по любому запросу get.

Решение было простым. Сначала удалите это. Во-вторых, настройте каждый компонент службы следующим образом

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")                       
            )
        )
)
...