Search code examples
wcfapp-configendpointsbase-address

Can several WCF services share a common BaseAddress?


I've got an assembly containing several WCF services, each with its own contract. It all works nicely. The service config in the app.config for the service looks like this:

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

Since I've got a bigger project in mind, with more contracts, I'd like to have a way to share the BaseAddress between the different service contracts.
If this would just be one service with different contracts and endpoints, I could set a ommon baseaddress, but how do I set a common baseaddress for more than one service?

Of course I'd need something similar for the client.


Solution

  • You can combine all contracts in one class, so you have one service with a baseaddress and one (or more) endpoint(s) per contract.

    To avoid having one large class-file you can use the partial-keyword (asuming you use c#) to split the class across multiple files. Each file can implement one contract, that makes maintaining the individual interfaces much easier.

    In C++ you can use #includes or multiple inheritance, but that imply a large amount of discipline...

    Your config would look like this:

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