Working with Multiple Contracts, Multiple Endpoints in WCF

A given WCF service can be configured to work with Http, TCP , old asmx clients, non .Net clients etc etc. — by just changing configuration values, anytime after the service has been developed/deployed. I assume you are familiar with Address,Binding and Contract components of WCF.If not then this link can help, —  http://msdn.microsoft.com/en-us/magazine/cc163647.aspx .Here in this example, I try to create different Endpoint combinations of a service residing in my Library. Following are few valid EndPoint generation combinations, in a given service.

Binding(B1) + Address(A1) + Contract(C1)  —>  valid EndPoint
Binding(B1) + Address(A2) + Contract(C1)  —>  valid EndPoint
Binding(B1) + Address(A1) + Contract(C2)  —>  valid EndPoint
Binding(B1) + Address(A1) + Contract(C3)  —>  valid EndPoint

Binding(B2) + Address(A2) + Contract(C1)  —>  valid EndPoint
Binding(B3) + Address(A3) + Contract(C1)  —>  valid EndPoint

For the above, the gist is —
1) Multiple EndPoints having same binding, but different contracts, can have same address.
2) Multiple EndPoints having different bindings, needs to have unique address.

I started with VS2010->Projects->NEW->WCF Service Library template. I added 2 WCFServices to this library — namely IHelloWorld and IByeWorld. Next I added one more ServiceContract “IMultipleContract” which is derived from IhelloWorld and IByeWorld interfaces. So IMultipleContract contains 2 Contracts. Next I rename my existing App.Config to something else — say AppOld.config. The point is, I will add a brand new ApplicationConfiguration file and make all necessary configuration changes using in-built WCF Configuration Editor.It’s a good choice to alter the configuration settings through configuration files & NOT in code , because then we don’t need to recompile & re-deploy the application, when we want to make the service work in different scenarios. My goal is to make this service (IMultipleContract), containing 2 differen contracts, — have different EndPoints, so that, if at all needed in future, it works with
— old ASMx or non-.Net clients through basicHttpBinding,
— .Net3.0 onwards clients with wsHttp or intranet-ready faster TCP binding. Hence I genearte 4 unique Endpoints. Other than for the TCP endPoint, I use common base Address and a path, to generate address information. Here’s how it goes.

1) basicHttpBinding Endpoint
Address=Base Address; Binding=basicHttpBinding; Contract=MyWCFLibrary.IMultipleContract;

2) WsHttpBinding EndPoint with Service Contract IhelloWorld
Address=Base Address+Path(test1); Binding=wsHttpBinding; Contract=MyWCFLibrary.IHelloWorld;

3) WsHttpBinding EndPoint with Service Contract IByeWorld
Address=Base Address+Path(test1); Binding=wsHttpBinding; Contract=MyWCFLibrary.IByeWorld;
Here’s the actual code and few screenshots of the WCF Configuration Editor.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace MyWCFLibrary
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IHelloWorld" in both code and config file together.
    [ServiceContract]
    public interface IHelloWorld
    {
        [OperationContract]
        string DoWork();
    }

    public class HelloWorld : IHelloWorld
    {
        public string DoWork()
        {
            return "Hello World";
        }
    }
}

namespace MyWCFLibrary
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IByeWorld" in both code and config file together.
    [ServiceContract]
    public interface IByeWorld
    {
        [OperationContract]
        string DoWork2();
    }
    public class ByeWorld : IByeWorld
    {
        public string DoWork2()
        {
            return "bye World";
        }
    }
}
namespace MyWCFLibrary
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IMultipleContract" in both code and config file together.
    [ServiceContract]
    public interface IMultipleContract : IHelloWorld, IByeWorld
    {
       
    }

    public class MultipleContract : IMultipleContract
    {
        public string DoWork()
        {
            return "Hello World Overidden";
        }

        public string DoWork2()
        {
            return "bye World overridden";
        }
    }

}

App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior name="MulContractService">
                    <serviceMetadata httpGetEnabled="true" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <bindings>
            <basicHttpBinding>
                <binding name="MulContractBasicBinding" />
            </basicHttpBinding>
            <netTcpBinding>
                <binding name="MulContractTCPBinding" />
            </netTcpBinding>
            <wsHttpBinding>
                <binding name="MulContractWsHttpBinding" />
            </wsHttpBinding>
        </bindings>
        <services>
            <service behaviorConfiguration="MulContractService" name="MyWCFLibrary.MultipleContract">
                <clear />
                <endpoint binding="basicHttpBinding" bindingConfiguration="MulContractBasicBinding"
                    name="MulContractBasicEndPoint" contract="MyWCFLibrary.IMultipleContract"
                    listenUriMode="Explicit">
                    <identity>
                      <dns value="localhost" />
                        <certificateReference storeName="My" storeLocation="LocalMachine"
                            x509FindType="FindBySubjectDistinguishedName" />
                    </identity>
                </endpoint>
                <endpoint address="test1" binding="wsHttpBinding" bindingConfiguration="MulContractWsHttpBinding"
                    name="MulContractWsHttp" contract="MyWCFLibrary.IByeWorld"
                    listenUriMode="Explicit">
                    <identity>
                      <dns value="localhost" />
                        <certificateReference storeName="My" storeLocation="LocalMachine"
                            x509FindType="FindBySubjectDistinguishedName" />
                    </identity>
                </endpoint>
                <endpoint address="test1" binding="wsHttpBinding" bindingConfiguration="MulContractWsHttpBinding"
                    name="MulContractWsHttp" contract="MyWCFLibrary.IHelloWorld"
                    listenUriMode="Explicit">
                    <identity>
                      <dns value="localhost" />
                        <certificateReference storeName="My" storeLocation="LocalMachine"
                            x509FindType="FindBySubjectDistinguishedName" />
                    </identity>
                </endpoint>
                <endpoint address="net.tcp://localhost:8733/Design_Time_Addresses/MyWCFLibrary/MultipleContract/"
                    binding="netTcpBinding" bindingConfiguration="MulContractTCPBinding"
                    name="MulContractTCPEndPoint" contract="MyWCFLibrary.IMultipleContract" />
                <host>
                    <baseAddresses>
                        <add baseAddress="http://localhost:8732/Design_Time_Addresses/MyWCFLibrary/MultipleContract/" />
                    </baseAddresses>
                </host>
            </service>
        </services>
    </system.serviceModel>
</configuration>

Finally did a F5 to run the app.

img1   Config1

config2

config3

config6

Here I have used the in-built WCF Test Client to make sure all my service endpoints works ok. That’s all about it. Comments/Suggestions welcome. Thanks for reading.

This entry was posted in WCF. Bookmark the permalink.

3 Responses to Working with Multiple Contracts, Multiple Endpoints in WCF

  1. Rajesh says:

    Nice one.

  2. praveen says:

    good Explanation

  3. kadhir says:

    Super Demo

Leave a reply to kadhir Cancel reply