<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8513759648388846562</id><updated>2011-08-01T11:56:23.138-07:00</updated><title type='text'>Code Stink</title><subtitle type='html'>All care, no responsibility etc, etc...</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://codestink.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513759648388846562/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://codestink.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Malcolm Young</name><uri>http://www.blogger.com/profile/11060109670290978219</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>1</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8513759648388846562.post-5622052260848268393</id><published>2010-03-12T23:51:00.000-08:00</published><updated>2010-03-15T19:05:34.475-07:00</updated><title type='text'>Standard Endpoints in WCF 4.0</title><content type='html'>&lt;div&gt;Sometimes you might want to add an endpoint to a service that doesn't exactly fit the normal WCF model. You might want to create something like what&amp;nbsp;the IMetadataExchange interface does&amp;nbsp;maybe or some sort of diagnostic endpoint. For the sake of discussion, let's call them &lt;em&gt;infrastructure endpoints.&lt;/em&gt; Whatever the need, infrastructure endpoints usually have two main characteristics that differentiate them from your everyday service contract:&lt;/div&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The implementation for the contract will be separate from the service class and,&lt;/li&gt;&lt;li&gt;You won't want metadata about the contract exposed from the service.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;If you haven't thought about this before, you may be thinking "How hard could this be? Build up a ServiceEndpoint in a behaviour, set some magic property to make the runtime know it's different, add it to the host using AddServiceEndpoint and sit back and enjoy.". For a number of reasons (mainly that the 'magic' property doesn't really exist), the reality is that in .Net 3.5 this process is actually a lot more involved. A number of blogs are floating around on the subject (e.g Patric Fornasier's &lt;a href="http://patforna.blogspot.com/2007/02/abusing-wcf-for-serving-http-get.html"&gt;excellent post&lt;/a&gt; and &lt;a href="http://winterdom.com/2006/11/hackingmywayintoanarbitraryendpointinawcfservice"&gt;this one by Tomas Restrepo&lt;/a&gt;) but essentially the process you'll end up following will go something like this (for simplicities sake we'll assume http transport):&lt;br /&gt;&lt;ol&gt;&lt;li&gt;You probably won't want to use one of the existing endpoint bindings for the service so you'll need to create a new IChannelListener. You'll also find out around now that you'll have to set some internal properties on your transport element (notably&lt;br /&gt;InheritBaseAddressSettings) in order for it to work using reflection which will make you feel dirty.&lt;/li&gt;&lt;li&gt;Once you've built your channel listener, you'll build your channel dispatcher.&lt;/li&gt;&lt;li&gt;Once you've built your channel dispatcher, you can go ahead and build your endpoint dispatcher.&lt;/li&gt;&lt;li&gt;You'll find that you have to provide an IInstanceProvider for the endpoint dispatcher's runtime. You'll discover that the only existing implementations for IInstanceProvider are internal to System.ServiceModel so you'll be writing that (or more likely, copying it out of reflector) yourself.&lt;/li&gt;&lt;li&gt;You'll also find the same thing for IInstanceContextProvider - all implementations internal, better break out reflector again.&lt;/li&gt;&lt;li&gt;You'll then have to create a DispatchOperation for each operation on your contract. WCF normally does this by using the super secret OperationInvokerBehavior, but that won't be an option for you as it's, yep - internal.&lt;/li&gt;&lt;li&gt;You'll then have to create a IDispatchMessageFormatter for each DispatchOperation unless you only use untyped operation parameters(i.e. only accepting and returning Message types). &lt;/li&gt;&lt;li&gt;Finally, you can put it all together and add your channel dispatcher to the host's ChannelDispatchers collection.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;If you haven't scratched your own eyes out by now then you should have a reasonable starting place for implementing reusable endpoints, but let me ask you - didn't that seem like a lot of effort?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Why is this process so convoluted in .Net 3.5? Well, the main reason is that many of the classes that do this work on behalf of WCF are internal and we have to implement the functionality ourselves. This is fair enough. There is a limit on what size an API Microsoft can expose and support, unfortunately this doesn't make our job any easier. But the more fundamental issue is the one alluded to at the start of the post - we can't use AddServiceEndpoint. Unfortunately most of the work that we had to perform manually above is performed as a result of this invocation. If you try to pass in a ServiceEndpoint with a contract your service class does not implement, WCF will throw and helpfully tell you so. Well, what about the IMetadataExchange interface I hear you ask? Good question, and here's the kicker - WCF checks whether the implementation class implements your class but specifically excludes the IMetadataExchange interface from this check. There is no extension point to tell the runtime to treat your contract the same way - WCF is literally doing things like &lt;em&gt;if(o is IMetadataExchange&lt;/em&gt;).... As a result, the only interface that can be implemented independently of your service AND that can be added to the service via AddServiceEndpoint is IMetadataExchange.&lt;br /&gt;&lt;br /&gt;Thankfully, this situation has been largely addressed in WCF 4.0 through the introduction of standard endpoints. Standard endpoints are types that inherit from ServiceEndpoint&amp;nbsp;that you can reference in the configuration file and&amp;nbsp;that&amp;nbsp;can be&amp;nbsp;preconfigured to some degree in code and therefore don't need to be fully configured via the config. For example:&lt;br /&gt;&lt;br /&gt;&amp;lt;service name="WcfService.Service"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;endpoint name="ws" contract="WcfService.IService" binding="wsHttpBinding" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;endpoint kind="ping" address="ping" /&amp;gt;&lt;br /&gt;&amp;lt;/service&amp;gt;&lt;br /&gt;&lt;br /&gt;The "kind" attribute identifies the type of standard endpoint. In this case the standard endpoint uses a configurable address but the binding and contract are provided by the standard endpoint. &lt;br /&gt;&lt;br /&gt;Standard endpoints are nice, but what's really nice is that the ServiceEndpoint base class now exposes&amp;nbsp;the boolean&amp;nbsp;property, IsSystemEndpoint that when set to&amp;nbsp;true, tells the runtime that the implementation of our contract is provided independently of the service class. In other words, it's the missing 'magic' property mentioned above!&lt;br /&gt;&lt;br /&gt;Enough babble. Here are the steps required to implement a simple standard&amp;nbsp;endpoint that uses the &lt;a href="http://msdn.microsoft.com/en-us/library/bb412169.aspx"&gt;REST Programming Model&lt;/a&gt;&amp;nbsp;to allow GET callers to 'ping' a service and receive a plain text 'OK' in return. Not very useful, I know - but enough to demonstrate the basic concept. Our endpoint will sit at the address /ping under our service.&lt;br /&gt;&lt;br /&gt;First, we define the interface and implementation:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;[ServiceContract]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;public interface IPing&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [WebGet(UriTemplate="")]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Stream Hello();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;public class Ping : IPing&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Stream Hello()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var ms = new MemoryStream();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var w = new StreamWriter(ms);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;w.Write("OK");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; w.Flush();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ms.Position = 0;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return ms;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;Pretty much nothing to see here, except that in WCF 4.0 you no longer need to specify the OperationContract attribute if you use the WebGet attribute. Otherwise this is all standard .Net 3.5 REST model stuff.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Next, we'll define the actual standard endpoint:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;public class PingEndpoint:ServiceEndpoint&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; public PingEndpoint()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; :base(ContractDescription.GetContract(typeof(IPing)))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; { &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var binding = new WebHttpBinding();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;binding.Name = "pingBinding";&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;this.Binding = binding;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; this.Behaviors.Add(new WebHttpBehavior());&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; this.IsSystemEndpoint = true;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp;} &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;The critical thing to note here is the use of the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;IsSystemEndpoint&lt;/span&gt; &lt;/span&gt;&lt;span style="font-family: inherit;"&gt;property. This is what tells WCF that our implementation of &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;IPing&lt;/span&gt;&amp;nbsp;will not be found within the service implementation. Set this to false and you will get the same &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;InvalidOperationException &lt;/span&gt;&lt;span style="font-family: inherit;"&gt;that you would see in .Net 3.5 had you added an unimplemented contract via AddServiceEndpoint. Setting this value to true also prevents the service from emitting any metadata about the endpoint.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;That's most of the hard work out of the way but sadly, Microsoft has not been kind enough to expose everything for us. We still need to write our own implementations of &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;IInstanceProvider&lt;/span&gt; and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;IInstanceContextProvider. &lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;Below are a couple of implementations of these&amp;nbsp;based on what you can find in reflector that employ a singleton instance:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;internal class InstanceProvider : IInstanceProvider&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; private object _instance;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; internal InstanceProvider(object instance)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (instance == null)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw new ArgumentNullException("instance");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;_instance = instance;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public object GetInstance(InstanceContext instanceContext)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return _instance;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; public object GetInstance(InstanceContext instanceContext, Message message)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return _instance;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;public void ReleaseInstance(InstanceContext instanceContext, object instance)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IDisposable disposable = instance as IDisposable;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (disposable != null)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; disposable.Dispose();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;internal class SingletonInstanceContextProvider : IInstanceContextProvider&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; private InstanceContext _instanceContext;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; private object _syncRoot = new object();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; private ManualResetEvent _isInitialised;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; public InstanceContext GetExistingInstanceContext(Message message, IContextChannel channel)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (_instanceContext != null)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _instanceContext = WaitForInstanceContext();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return _instanceContext;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; public void InitializeInstanceContext(InstanceContext instanceContext, Message message, IContextChannel channel)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lock (_syncRoot)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this._instanceContext = instanceContext;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (_isInitialised != null)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _isInitialised.Set();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; public bool IsIdle(InstanceContext instanceContext)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return false;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; public void NotifyIdle(InstanceContextIdleCallback callback, InstanceContext instanceContext) { }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; internal InstanceContext WaitForInstanceContext()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; bool wait = false;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (_instanceContext == null)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lock (_syncRoot)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (_instanceContext == null)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (_isInitialised == null)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _isInitialised = new ManualResetEvent(false);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;wait = true;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (wait)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _isInitialised.WaitOne();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _isInitialised.Close();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return _instanceContext;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;Once that's done, you'll need a behaviour to attach your instances of these types to the runtime like so:&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;public class PingBehavior : IServiceBehavior&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;{ &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; public void ApplyDispatchBehavior(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (ChannelDispatcherBase baseDispatcher in serviceHostBase.ChannelDispatchers)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ChannelDispatcher dispatcher = baseDispatcher as ChannelDispatcher;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (dispatcher != null &amp;amp;&amp;amp; isPingDispatcher(dispatcher))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var dispatchRuntime = dispatcher.Endpoints[0].DispatchRuntime;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var pingService = new Ping();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dispatchRuntime.InstanceProvider = new InstanceProvider(pingService);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dispatchRuntime.InstanceContextProvider = new SingletonInstanceContextProvider();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; private bool isPingDispatcher(ChannelDispatcher dispatcher)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return dispatcher.Endpoints[0].ContractName == "IPing";&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Courier New;"&gt;...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;We're now pretty much done. All that remains is configuration support. I'll assume you know how to hook up the service behaviour above and just focus on what's required for the endpoint. First, we derive a class from &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;StandardEndpointElement&lt;/span&gt; specific to our standard endpoint:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;public class PingEndpointElement : StandardEndpointElement&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;{ &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; protected override Type EndpointType&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return typeof(PingEndpoint); }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; protected override ServiceEndpoint CreateServiceEndpoint(ContractDescription contract)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return new PingEndpoint();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; protected override void OnApplyConfiguration(ServiceEndpoint endpoint, ServiceEndpointElement serviceEndpointElement)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PingEndpoint customEndpoint = (PingEndpoint)endpoint;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; protected override void OnApplyConfiguration(ServiceEndpoint endpoint, ChannelEndpointElement channelEndpointElement)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PingEndpoint customEndpoint = (PingEndpoint)endpoint;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; protected override void OnInitializeAndValidate(ServiceEndpointElement serviceEndpointElement)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; protected override void OnInitializeAndValidate(ChannelEndpointElement channelEndpointElement)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;The last class we need is a subclass of &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;StandardEndpointCollectionElement&lt;t, u=""&gt;. &lt;/span&gt;&lt;span style="font-family: inherit;"&gt;It only needs to be declared, not implemented at this stage:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;public class PingEndpointCollectionElement : StandardEndpointCollectionElement&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;We're finally there. We add the above type to the new endpointExtension configuration section:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;system.serviceModel&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;extensions&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;endpointExtensions&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name="ping" type="WcfService1.PingEndpointCollectionElement, WcfService1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/endpointExtensions&amp;gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;Assuming you've added the service behaviour we defined above to the behaviours collection either programmatically or via configuration you should now be able to add the endpoint to the service configuration just like above:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;lt;service name="WcfService.Service"&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;lt;endpoint name="ws" contract="WcfService.IService" binding="wsHttpBinding" /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;endpoint kind="ping" address="ping" /&amp;gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;lt;/service&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;OK, it still requires some effort but adding these sort of endpoints is a lot more straightforward now in WCF 4.0 than it was&amp;nbsp;with 3.5.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513759648388846562-5622052260848268393?l=codestink.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codestink.blogspot.com/feeds/5622052260848268393/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codestink.blogspot.com/2010/03/standard-endpoints-in-wcf-40.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513759648388846562/posts/default/5622052260848268393'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513759648388846562/posts/default/5622052260848268393'/><link rel='alternate' type='text/html' href='http://codestink.blogspot.com/2010/03/standard-endpoints-in-wcf-40.html' title='Standard Endpoints in WCF 4.0'/><author><name>Malcolm Young</name><uri>http://www.blogger.com/profile/11060109670290978219</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>
