WCF: A self-hosted service with multiple endpoints

Last night I started playing with more more interesting things in WCF (multiple endpoints) and I kept running into a wall: how do you set more than one http endpoint on the same service!? Nothing I was doing was working, then I ran into Indigo Girl's WCF book chapters online (see my next post). Her examples clearly explain what I was doing wrong. Let me explain how to do what I wanted to do in my own words...

Instead of having a different "server" for each endpoint of the same address scheme (i.e. http), you have a a base address for and then give each a name. There is one WSDL for all the endpoints of a service. That is: one service, one WSDL; not one endpoint, one WSDL. This stems from the fact that by default there are two endpoints repackages: mex and HTTP Get. The HTTP get one is the one that will help out with the WSDL.

Here is the fixed up code. By running this up and generating the proxy, we are able to have the complete mechanism for communication from the client to the service, including the configuration file (below).

Program.cs
Uri httpUri = new Uri("http://localhost:8081/");
using(ServiceHost hService = new ServiceHost(typeof(DemoService), httpUri)) {
 hService.AddServiceEndpoint(typeof(IDemoService), new BasicHttpBinding( ), "BasicService");
 hService.AddServiceEndpoint(typeof(IDemoService), new WSDualHttpBinding( ), "DualHttpService");

 hService.Open( );

 Console.WriteLine("Listening...");
 Console.ReadLine( );
}
client app.config

  <system.serviceModel>
    <client>
      <endpoint
        address="http://localhost:8081/BasicService"
        binding="basicHttpBinding"
        name="BasicHttpService"
        contract="IDemoService" />
      <endpoint
        address="http://localhost:8081/DualHttpService"
        binding="wsDualHttpBinding"
        name="DualHttpService"
        contract="IDemoService" />
    </client>
  </system.serviceModel>
Even when using entitely different protocols (the higher level http and say the lower level tcp), you have one WSDL. Of course in this case, since there are more one address scheme (http and net.tcp), you have more than one base address; one per scheme.
Program.cs
Uri netTcpAddress = new Uri("net.tcp://localhost:8080/");
Uri httpAddress = new Uri("http://localhost:8081/");
using (ServiceHost service = new ServiceHost(typeof(DemoService), new Uri[] { netTcpAddress, httpAddress })) {
 service.Open( );

 Console.WriteLine("Listening...");
 Console.ReadLine( );
}
server app.config

  <system.serviceModel>
    <services>
      <service type="WcfDemo.DemoService">
        <endpoint
          address="NetTcpService"
          contract="WcfDemo.IDemoService"
          binding="netTcpBinding"
          />
        <endpoint
          address="DualHttpService"
          contract="WcfDemo.IDemoService"
          binding="wsDualHttpBinding"
          />
      </service>
    </services>
  </system.serviceModel>
client app.config

  <system.serviceModel>
    <client>
      <endpoint
        address="net.tcp://localhost:8080/NetTcpService"
        binding="netTcpBinding"
        name="NetTcpService"
        contract="IDemoService" />
      <endpoint
        address="http://localhost:8081/DualHttpService"
        binding="wsDualHttpBinding"
        name="DualHttpService"
        contract="IDemoService" />
    </client>
  </system.serviceModel>

As you can see WCF really allows for some pretty powerful scenarios...