Вопрос

У меня есть сборка, содержащая несколько сервисов WCF, каждый со своим контрактом. Все работает хорошо. Конфигурация службы в app.config для службы выглядит следующим образом:

<services>
  <service behaviorConfiguration="WcfService.AlyzaServiceBehavior"
    name="Sam.Alyza.WcfService.ServiceWebsites">
    <endpoint address="" binding="netTcpBinding" contract="Sam.Alyza.WcfInterface.IServiceWebsites">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
    <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
    <host>
      <baseAddresses>
        <add baseAddress="net.tcp://localhost:8731/Design_Time_Addresses/SamAlyza/Websites/" />
      </baseAddresses>
    </host>
  </service>
  <service behaviorConfiguration="Sam.Alyza.WcfService.LogReaderServiceBehavior"
    name="Sam.Alyza.WcfService.ServiceLogReader">
    <endpoint address="" binding="netTcpBinding" contract="Sam.Alyza.WcfInterface.IServiceLogReader">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
    <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
    <host>
      <baseAddresses>
        <add baseAddress="net.tcp://localhost:8731/Design_Time_Addresses/SamAlyza/LogReader/" />
      </baseAddresses>
    </host>
  </service>
  <service behaviorConfiguration="Sam.Alyza.WcfService.ServiceSystemverwaltungBehavior"
    name="Sam.Alyza.WcfService.ServiceSystemverwaltung">
    <endpoint address="" binding="netTcpBinding" contract="Sam.Alyza.WcfInterface.IServiceSystemverwaltung">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
    <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
    <host>
      <baseAddresses>
        <add baseAddress="net.tcp://localhost:8731/Design_Time_Addresses/SamAlyza/Systemverwaltung/" />
      </baseAddresses>
    </host>
  </service>
  [...]
</services>

Поскольку я имею в виду более крупный проект с большим количеством контрактов, я хотел бы иметь возможность разделить BaseAddress между различными сервисными контрактами.
Если бы это был только один сервис с разными контрактами и конечными точками, я мог бы установить базовый адрес ommon, но как мне установить общий базовый адрес для более чем одного сервиса?

Конечно, мне нужно что-то подобное для клиента.

Это было полезно?

Решение

Вы можете объединить все контракты в одном классе, поэтому у вас есть один сервис с базовым адресом и одна (или более) конечная (ые) точка (и) на контракт.

Чтобы не иметь один большой файл класса, вы можете использовать ключевое словоpart (если вы используете c #), чтобы разделить класс на несколько файлов. Каждый файл может реализовывать один контракт, что значительно упрощает обслуживание отдельных интерфейсов.

В C ++ вы можете использовать #include или множественное наследование, но это подразумевает большой объем дисциплины ...

Ваша конфигурация будет выглядеть так:

<services>
  <service behaviorConfiguration="WcfService.AlyzaServiceBehavior"
    name="Sam.Alyza.WcfService.ServiceAll">
    <endpoint address="Websites/" binding="netTcpBinding" contract="Sam.Alyza.WcfInterface.IServiceWebsites">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
    <endpoint address="LogReader/" binding="netTcpBinding" contract="Sam.Alyza.WcfInterface.IServiceLogReader">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
    <endpoint address="Systemverwaltung/" binding="netTcpBinding" contract="Sam.Alyza.WcfInterface.IServiceSystemverwaltung">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
    <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
    <host>
      <baseAddresses>
        <add baseAddress="net.tcp://localhost:8731/Design_Time_Addresses/SamAlyza/" />
      </baseAddresses>
    </host>
  </service>
</services>

Другие советы

Сервисы могут использовать значения BaseAddress (включая номера портов, если запущена служба общего доступа к портам Net.Tcp). Это адреса конечных точек, которые должны быть уникальными. Обратите внимание, что в вашем конфигурационном файле конечные точки MEX для каждого ServiceHost имеют адрес «mex». Ваши другие конечные точки имеют адрес пустой строки. Когда вы предоставляете относительный адрес для конечной точки WCF (по крайней мере, в файле конфигурации), базовый адрес добавляется к нему. Следовательно, адрес конечной точки MEX для службы LogReader: «net.tcp: // localhost: 8731 / Design_Time_Addresses / SamAlyza / LogReader / mex " ;.

Поскольку относительный адрес не был задан в основной конечной точке службы, базовый адрес ServiceHost используется в качестве фактического адреса для основной конечной точки службы. Поскольку никакие две конечные точки не могут иметь перекрывающиеся значения Uri.AbsolutePath, ваш пример заставит вас поверить, что значения базового адреса не могут быть общими. Класс ServiceHost, в котором размещаются службы WCF, не имеет встроенной конечной точки, тогда как класс ServiceEndpoint имеет свойство ListenUri, которое будет заполняться на основе предоставленных вами настроек.

Если вы измените значения baseAddress в своем примере на все совпадения, при условии, что вы задаете уникальные относительные значения адресов для элементов Endpoint, все должно работать. Тем не менее, кажется, что вы можете столкнуться с некоторыми проблемами с конечными точками MEX, так как все они имеют адрес «mex». В настоящее время. Сделайте это уникальным, и у вас все будет хорошо.

Теперь, я должен спросить, вы уверены, что вы не просто хотите, чтобы эти службы разделяли пространство имен, а не базовые адреса?

Вы также можете установить базовые адреса в коде, если используете пользовательский ServiceHostFactory.

В конфиге вы можете настроить некоторые параметры приложения:

<configuration>
  <appSettings>
    <add key="BaseAddress" value="http://localhost:1234" />
  </appSettings>
<configuration>

Затем создайте собственный ServiceHostFactory:

public sealed class MyServiceHostFactory : ServiceHostFactory
{
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        var baseAddy = ConfigurationManager.AppSettings["BaseAddress"];
        baseAddresses.Add(new Uri(baseAddy));
        return new ServiceHost(serviceType, baseAddresses);
    }

}

Затем вам также нужно изменить файлы .svc, чтобы использовать эту фабрику:

<%@ ServiceHost Language="C#" Debug="true" Service="MyApp.MyService" CodeBehind="MyService.svc.cs" Factory="MyApp.MyServiceHostFactory" %>
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top