Pergunta

Eu tenho uma montagem contendo vários serviços WCF, cada um com seu próprio contrato. Tudo funciona muito bem. A configuração do serviço no app.config para os olhares de serviços como este:

<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>

Desde que eu tenho um projeto maior em mente, com mais contratos, eu gostaria de ter uma maneira de compartilhar o BaseAddress entre os diferentes contratos de serviços.
Se este seria apenas um serviço com diferentes contratos e endpoints, eu poderia definir um baseaddress ommon, mas como faço para definir um baseaddress comum para mais de um serviço?

É claro que eu preciso de algo semelhante para o cliente.

Foi útil?

Solução

Você pode combinar todos os contratos em uma classe, então você tem um serviço com um baseaddress e um (ou mais) endpoint (s) por contrato.

Para evitar que uma grande classe-arquivo que você pode usar a palavra-chave parcial (asuming você usa c #) para dividir a classe em vários arquivos. Cada arquivo pode implementar um contrato, que faz com que a manutenção das interfaces individuais muito mais fácil.

Em C ++ você pode usar # inclui ou herança múltipla, mas isso implica uma grande quantidade de disciplina ...

A sua configuração ficaria assim:

<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>

Outras dicas

Os serviços podem compartilhar valores BaseAddress (incluindo port # 's, se a porta de serviço de compartilhamento Net.Tcp está em execução). É o endpoint endereços que deve ser exclusivo. Observe no seu arquivo de configuração que os endpoints MEX para cada ServiceHost ter um endereço de "mex". Seus outros parâmetros têm um endereço de string vazia. Quando você fornece um endereço relativo para um endpoint para WCF (no arquivo de configuração, pelo menos), o endereço base é anteposto a ele. Portanto, o endereço de endpoint MEX para o serviço LogReader é "net.tcp: // localhost: 8731 / Design_Time_Addresses / SamAlyza / LogReader / mex".

Uma vez que o endereço de um parente não foi definido no terminal de serviço principal, o endereço base do ServiceHost é usado como o endereço real para o terminal de serviço principal. Porque não há dois endpoints pode ter sobreposição de valores Uri.AbsolutePath, o seu exemplo seria levam a crer que os valores de endereço de base não pode ser compartilhada. A classe ServiceHost que hospeda serviços WCF não tem um built-in de terminais, enquanto a classe ServiceEndpoint tem uma propriedade listenUri que será preenchida com base nas configurações que você fornece.

Se você alterar os valores BaseAddress no seu exemplo para toda a partida, desde que você definir valores de endereço relativo exclusivos sobre os elementos terminais, tudo deve funcionar. No entanto, parece que você pode executar em alguns desafios com os endpoints MEX, uma vez que todos eles têm o endereço de "mex" atualmente. Fazer aqueles única e você deve ser fino.

Agora, devo perguntar, você tem certeza que você não está simplesmente querendo estes serviços para compartilhar um espaço de nomes, em vez de endereços de base?

Você também pode definir os endereços base no código se você usar um ServiceHostFactory personalizado.

Em config você pode ter algum ajuste app:

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

Em seguida, fazer uma ServiceHostFactory personalizado:

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);
    }

}

Em seguida, você também tem que mudar seus arquivos .svc usar essa fábrica:

<%@ ServiceHost Language="C#" Debug="true" Service="MyApp.MyService" CodeBehind="MyService.svc.cs" Factory="MyApp.MyServiceHostFactory" %>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top