Implementing a Custom Endpoint Selector
A custom endpoint selector is a class that implements the Microsoft.ConnectedIndustry.ServiceModel.IEndpointSelector interface. This interface is defined in the Microsoft.ConnectedIndustry.ServiceModel assembly. For more information about the IEndpointSelector interface, see The IEndpointSelector Interface.
You implement the SelectEndPoint method to return a service endpoint as a System.ServiceModel.Description.ServiceEndpoint object. For more information about the ServiceEndpoint class, see The ServiceEndpoint Class. The SelectEndPoint method takes the following parameters:
- A System.ServiceModel.Description.ServiceEndpointCollection object that contains a list of service endpoints that the SelectEndPoint method can select from.
- A string object that specifies the name of the service contract specified by the client application.
- A string object that specifies the namespace of the service contract specified by the client application.
The following code example shows the default endpoint selector class provided with DCS, Microsoft.ConnectedIndustry.ServiceModel.BasicEndpointSelector, in the Microsoft.ConnectedIndustry.ServiceModel assembly. The SelectEndPoint method simply returns the first service endpoint from the service endpoint collection that matches the contract and contract namespace specified by the client application. If there is no matching endpoint available, the method returns a null value.
Note: |
|---|
| After the Discovery Service returns a list of service endpoints to the client proxy that match the required scope and contract of the client application and the client proxy selects the service instance to use, the client proxy performs a WS-MetadataExchange operation with the service to retrieve the service metadata. If the service implements multiple endpoints, this metadata will contain information about each endpoint, including those that do not implement the service contract specified by the client application. Therefore, it is important that an endpoint selector examines the contract and contract namespace before selecting an endpoint to use. |
public ServiceEndpoint SelectEndPoint(ServiceEndpointCollection serviceCollection, string contractName, string contractNamespace)
{
ServiceEndpoint endpoint = null;
source.TraceEvent(TraceEventType.Verbose, 0, "BasicEndpointSelector::SelectEndPoint - Searching for an endpoint with contractName={0} and contractNamespace={1}", new object[] { contractName, contractNamespace });
foreach (ServiceEndpoint endpoint2 in serviceCollection)
{
source.TraceEvent(TraceEventType.Verbose, 0, "BasicEndpointSelector::SelectEndPoint - Found an endpoint with contractName={0} and contractNamespace={1}", new object[] { endpoint2.Contract.Name, endpoint2.Contract.Namespace });
if (endpoint2.Contract.Name.Equals(contractName) && endpoint2.Contract.Namespace.Equals(contractNamespace))
{
endpoint = endpoint2;
source.TraceEvent(TraceEventType.Verbose, 0, "BasicEndpointSelector::SelectEndPoint - Found the endpoint with the contract required");
break;
}
}
if (endpoint == null)
{
source.TraceEvent(TraceEventType.Verbose, 0, string.Format("BasicEndpointSelector::SelectEndPoint - No endpoint found with contractName={0} and contractNamespace={1}", contractName, contractNamespace));
}
return endpoint;
}
The next code example shows a custom endpoint selector called MyCustomEndpointSelector that is optimized for a client application that sends and receives messages containing BLOB data. The SelectEndPoint method examines the bindings of each service endpoint in the service endpoints collection, and if there are two or more endpoints that match the service contract and contract namespace specified by the client application, the endpoint selector gives preference to an endpoint that uses MTOM encoding. If no endpoints in the service endpoint collection implement the MTOM encoding, then the first endpoint in the collection is selected by default.
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.ConnectedIndustry.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Channels;
namespace DCS.Samples.Extensions
{
public class MyCustomEndpointSelector : IEndpointSelector
{
public ServiceEndpoint SelectEndPoint(
ServiceEndpointCollection serviceCollection,
string contractName, string contractNamespace)
{
ContractDescription serviceContract;
CustomBinding customBinding;
foreach (ServiceEndpoint serviceEndpoint in serviceCollection)
{
serviceContract = serviceEndpoint.Contract;
if (serviceContract.Name.Equals(contractName)
&& serviceContract.Namespace.Equals(contractNamespace))
{
customBinding = serviceEndpoint.Binding as CustomBinding;
//Give preference to service having MTOM encoding element
if (customBinding != null && customBinding.Elements.Find<MtomMessageEncodingBindingElement>() != null)
{
return serviceEndpoint;
}
}
}
//Select first endpoint having matching contract name and namespace
foreach (ServiceEndpoint serviceEndpoint in serviceCollection)
{
serviceContract = serviceEndpoint.Contract;
if (serviceContract.Name.Equals(contractName)
&& serviceContract.Namespace.Equals(contractNamespace))
{
return serviceEndpoint;
}
}
return null;
}
}
}
Note: