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.
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.
Nice one.
good Explanation
Super Demo