What if you wanted to control the number of active connections to a resource from BizTalk Adapters? For instance, suppose your resource endpoint has a limitation of the number of active connections. You could try to use the maximum connection limit, if provided by the adapter, but even then, would that work across the instances of that adapter running in your BizTalk Group?



The solution is to add a custom behavior, since this capability is not available out of the box. Fortunately, WCF is extensible. And extensibility is relatively easy to implement. But you need to pay your pound of flesh otherwise you may be tripping over yourself adding extensibility in one place, only to be overwritten without any intimation in another place. I hope to give you a little head start with this post.


Figure 1: WCF Interfaces

Before we start, since we are dealing with communications, get your favorite packet sniffing tool. Mine is Microsoft Message Analyzer. It replaces my previous favorite, Network Monitor. On the other hand, if these interface-intrusive sniffers cause you side effects with routing or virtualization, you may switch to the relay types (Fiddler, for example[i]). Sniffing is optional for our exercise; useful if you wish to eyeball raw bits. If you have been exploring WCF for any length of time, chances are you made your choice of sniffers a long time ago.


Figure 2Extensibility Artifacts

To introduce base concepts, without too much effort, let’s start with a very simple C# Console App that implements a service all in code using WCF LOB SDK (take a look at the Contoso and Echo adapter samples; especially how the SDK utilizes Channels):

using System;
usingSystem.ServiceModel;
using System.ServiceModel.Description;

namespace ExtendWCF
{
    class Program
    {
        [ServiceContract]
        public interface IService
        {
            [OperationContract]
            string DoSomething(string data);
        }
        public class Service : IService
        {
            public stringDoSomething(string data)
            {
                return $"Doing something with {data}";
            }
        }
        static void Main(string[] args)
        {
            string addr = $"http://{Environment.MachineName}:48000/Service";
            ServiceHost srv = new ServiceHost(typeof(Service), new Uri(addr));
            ServiceEndpoint endpoint = srv.AddServiceEndpoint(typeof(IService),
                new BasicHttpBinding(), "");
            srv.Open();
            ChannelFactory<IService> factory = new ChannelFactory<IService>(
                new BasicHttpBinding(), new EndpointAddress(addr));
            IService client = factory.CreateChannel();
            Console.WriteLine("Response from service: " + client.DoSomething("junk"));
            srv.Close();
        }
    }
}

Here I am arbitrarily using port 48000 (old habit using non-privileged ports as in higher the better). This somewhat simplistic single threaded example is blog friendly, and avoids having to explain disparate artifacts like configuration files. But it gets us started. Now we want to add some extension, behaviorally. Although throttling is a built-in capability in most if not all BizTalk WCF Adapters, but let’s add something similar, conceptually, but something we can control programmatically a la extensions. Let’s add the custom behavior that the server will only Do Something when message count is a multiple of 5 (of course had this been a useful real life function, we’d make it configurable. But here, we want minimalistic approach just to do a Proof of Concept or POC).

Figure 3Extensibility Points
The first question is where do we add that behavior? Is this behavior part of Description of the service? No, it is not possible to specify this behavior in terms of Service Level Agreement (SLA) or other declarative terms within service’s Description; it is just too arbitrary. It is obvious that we need some runtime default behavior to be extended, even. WCF allows extensibility in Error Handling, Formatteers, Instancing, Interceptors, Meta-Data, and so on. In terms of implementation, it is done through attributes, code, and configuration. We want to see if we can implement this in code first (blog friendly!).

POC.

Let’s write the ability/capability list for our POC:
  • 1.Accept messages send via a send port
  • 2.     Accumulate message without sending them to endpoint until message count is an exact multiple of 5
  • 3.     Out of Scope. Multiple instances of the adapter in a BizTalk Group. (This would require more implementation to coordinate Group level behavior and possibly require some centralized resource like a database). 
Figure 4 POC





[i]There is no endorsement of any 3rd party product, service, or offering.