If you know EndPoints well, you know WCF well. Configuring EndPoints are vital for any WCF design. You can configure EndPoints either via code or in web.config file. I have seen many times, developers are confused with EndPoints. I have come across following common question about EndPoints
- Can we have multiple EndPoints?
- Can be expose same contracts on more than one EndPoint?
- How base address works with EndPoints?
- Can we have more than one base address?
- How to configure EndPoint in code?
- Do we need to configure EndPoint in self hosting?
- Can we have more than one Service Contract?
And many more questions of such like above.
To answer above questions, let us start with understanding what is EndPoint?
Endpoint identifies a WCF Service. EndPoint is combination of Address, Contract and Binding. Mathematically EndPoint can be defined as below,
Where A, B and C are as follows,
Now it is simple mathematical addition rule that if we change any of A, B or C value then we will get new E. So for any reason if you change either of Address, Contract or Binding then a new EndPoint will get created. You may have multiple EndPoints of same service
- If same Service hosted on Multiple Address with same Binding and same Contract
- If same Service with different Contract on same Address and for same Binding
- If same Service with different Bindings on same Address and for same Contract.
We can say,
As a Service designer you may consider to create multiple EndPoints in following scenarios.
- Service wants to expose more than one type of binding.
- Service wants to expose more than one contract on the same binding.
- Service wants to expose same binding and contract on different addresses.
Multiple Binding Scenario
Now let us see how we can expose a Service on two different bindings using multiple EndPoints. For two different bindings, we will create two different EndPoints.
Let us say we have a service as below,
public interface IService1 { [OperationContract] string message(string name); }
And Service is implemented as below,
public class Service1 : IService1 { public string message(string name) { return "Hello " + name; } }
We can configure multiple EndPoints as,
<service name="MessagePatternDemo.Service1"> <endpoint name="ep1" address="/ep1" binding="basicHttpBinding" contract="MessagePatternDemo.IService1"/> <endpoint name="ep2" address="/ep2" binding="wsHttpBinding" contract="MessagePatternDemo.IService1" /> <endpoint name="mex" contract="IMetadataExchange" address="mex" binding="mexHttpBinding" /> </service>
In above configuration we are creating two EndPoints for the same service. Same Service is exposed on different bindings. Client can access same service either on basicHttpBinding or wsHttpBinding. Both EndPoints are identified with different names like ep1 and ep2. In multiple EndPoints each EndPoint will be exposed on different address with different names
At client side same service can be consumed by passing EndPoint name.
Service1Client proxy1 = new Service1Client("ep1"); var message = proxy1.message("dj"); Console.WriteLine(message); Console.ReadKey(true);
We are passing ep1 as name of the EndPoint, so client will consume service using basicHttpBinding. If you do not pass EndPoint name at time of proxy creation then run time error will get occur while calling service.
In above scenario, we exposed same service on multiple bindings using two different EndPoints.
Multiple Address Scenario
There could be scenario when you may want to expose same service on multiple base address. You can have more than one base address in service. Base address is created under host as below,
You can add more than one base address using add in baseAddresses section.Advantage of having base address is that, if we are moving service from one server to another then only base address need to be changed and all EndPoint will work on updated server. WCF allow us to give multiple base addresses for each type of protocol. And at the run time corresponding endpoint will take the base address.
So you can expose IService1 on multiple EndPoint with more than one binding as below. We are exposing IService1 with basicHttpBinding and netTcpBinding both. At the run time WCF will attach corresponding base address to respective binding.
<services> <service name="MessagePatternDemo.Service1"> <endpoint name="ep1" address="/ep1" binding="basicHttpBinding" contract="MessagePatternDemo.IService1"/> <endpoint name="ep2" address="/ep2" binding="netTcpBinding" contract="MessagePatternDemo.IService1"/> <endpoint contract="IMetadataExchange" address="mex" binding="mexHttpBinding" /> <endpoint address="mex1" binding="mexTcpBinding" contract="IMetadataExchange"/> <host> <baseAddresses> <add baseAddress="http://localhost:8081"/> <add baseAddress="net.tcp://localhost:8082"/> </baseAddresses> </host> </service> </services>
You may want to host same service on different server, in that scenario also service will have same contract and binding whereas different address.
Multiple Contract Scenario
There could be scenario when you will have to expose multiple Service Contracts. Service Contracts will be exposed on separate EndPoints.
Let us say we have two services IService1 and IService2 as below,
[ServiceContract] public interface IService1 { [OperationContract] string messagefromservice1(string name); } [ServiceContract] public interface IService2 { [OperationContract] string messagefromservice2(string name); }
And Service is implemented as below,
public class Service1 : IService1, IService2 { public string messagefromservice2(string name) { return "Hello " + name + " from service1"; } public string messagefromservice1(string name) { return "Hello " + name + " from service2"; } }
In config file we have created multiple EndPoints exposing IService1 and IService2 as below,
<services> <service name="MessagePatternDemo.Service1"> <endpoint name="ep1" address="/ep1" binding="basicHttpBinding" contract="MessagePatternDemo.IService1"/> <endpoint name="ep2" address="/ep2" binding="basicHttpBinding" contract="MessagePatternDemo.IService2"/> <endpoint contract="IMetadataExchange" address="mex" binding="mexHttpBinding" /> <host> <baseAddresses> <add baseAddress="http://localhost:8081"/> </baseAddresses> </host> </service> </services>
At client side while consuming service you will get information that there are two service contracts as part of the service. As you see in Add Service Reference dialog that there are two services listed and they are IService1 and IService2
To use these service you will have to create separate proxies. Both services can be consumed at client as below,
Service1Client proxy1 = new Service1Client(); var message = proxy1.messagefromservice1("dj"); Console.WriteLine(message); Service2Client proxy2 = new Service2Client(); var message1 = proxy2.messagefromservice2("dj"); Console.WriteLine(message1); Console.ReadKey(true);
On running you will get output as below,
Having multiple EndPoints for services are sometime essential for a good service design. You may want to expose same service on different EndPoint for Internet user whereas for Intranet user on separate EndPoint. I hope this post is useful for you.
Leave a Reply