Dynamic send ports allow adapter properties to be set at runtime (and also to select the adapter to be used). In my particular BizTalk 2009 scenario, I was creating a WCF dynamic send port to call a service endpoint URI only known at runtime, specified by the client (my orchestration is designed to be a generic message broker).
My first dislike was WCF configuration had to be defined programmatically in my orchestration. Sure, I was storing the properties in a custom SSO application so they weren’t hardcoded, but the BizTalk admin console provides a standard mechanism to configure WCF properties and it made sense to use it. Thinking of the BizTalk admins, I didn’t like the idea of hiding configuration away and then in a non standard way: it makes troubleshooting more difficult.
Secondly: performance. A few of my colleagues and sources on the web advised of poor performance using dynamic send ports for these reasons:
1. A dynamic send port is created each time it is used and in the case of WCF, for instance, the channel stack is created each time. This can have a significant performance hit. Further information about this is available here.
2. Only the default handler for each transport can be used which is a potential performance bottleneck if the host instance used by the default handler hasn’t been optimized for send operations. This limitation is also a recipe for inconsistent configuration (for example, if a design decision has been made to use a particular host for particular functions, this will not enforceable) and also it isn’t obvious to the BizTalk admins, what handler is used for a particular port. (Note that this limitation has been removed in BizTalk 2013 where it is now possible to choose a host instance for a dynamic send port, other than being stuck with just the default handler).
So I decided to use a static send port and override the “dummy” URI in my send port with the actual URI provided by the client… I did this as follows:
1. In my orchestration, in a Construct Message shape, I assigned to my own custom context properties, values that would later to be used to populate the BTS.OutboundTransportLocation and WCF.Action properties (these specify the endpoint URI and SOAP operation used by the WCF adapter, respectively). I did this instead of assigning directly to the “out of the box” properties since both were later overwritten on receipt of the message by the send port.
2. Using a custom pipeline component, I then promoted properties BTS.IsDynamicSend, BTS.OutboundTransportLocation and WCF.Action in a send pipeline assigned to the send port, populating BTS.OutboundTransportLocation and WCF.Action using the values assigned to my custom context properties like this:
inmsg.Context.Promote(“IsDynamicSend”, “http://schemas.microsoft.com/BizTalk/2003/system-properties”, true); // Set this to prevent URL caching.
inmsg.Context.Promote(“OutboundTransportLocation”, “http://schemas.microsoft.com/BizTalk/2003/system-properties”, endpointURL);
inmsg.Context.Promote(“Action”, “http://schemas.microsoft.com/BizTalk/2006/01/Adapters/WCF-properties”, operationName);
Note that BTS.IsDynamicSend has been set to “true”. As mentioned on MSDN here, this causes the send adapter to not used cached configuration, but to read configuration from the message context each time the send port is used. If BTS.IsDynamicSend was not set for example, then the cached endpoint URI would be used over the endpoint URI actually stamped on the message which was not what I wanted, since it’s possible that the endpoint may change between calls.
Performance: running my SOAPUI load tests, the response times of my web service were the same after changing to use a static port over a dynamic port. I’m using the WCF-Custom adapter with wsHttpBinding in my static send port. The response time of my web service was already acceptable to my client and my main motivation in using a static send port was better configuration options using the BizTalk admin console (rather than storing configuration in a custom SSO application). However better perfomance would have been nice! If I have time, I may investigate this further across the different adapters.