Although current BizTalk release does not support .NET generics it doessupportconcept of genericity at the message level. It is possible, of course, through “untyped” messages ormessages that don’t havespecific type attached to their context.Such messages are represented as System.Xml.XmlDocument type in orchestrations. To read more on message typing aspect of BizTalk please refer to this excellent post by Charles Young. I’d likeshow practical examples of applying generic programming to typical BizTalk tasks. These examples will help to make your BizTalk solutions leaner,more flexible, andeasier to maintain.
Let’sstart with very common pattern where BizTalk is used as merely message dispatcher – Message Broker. The goal of our generic message brokerwill beto dispatch any type of message to its destinationdecided at runtime. So,by avoiding type dependency and early routing binding (basically, hardcoding) we would get single very flexible orchestration which can easily handle requirement changes -one of the top goals of good application design.
Some things to consider beforecreating BizTalk orchestration. First, we need to figure out how and where to store input to output destination map. Since, it’s just key-value pairs, application configuration file will work fine. In my work, I prefer to keep collections of homogenous setting like this in separate xml config files and read them in custom XmlSerializable map (objects like NameValueCollectionor Dictionary being non XmlSerializablewon’t work in orchestration unless placed inside atomic transaction scope). Let’s keep it in application configuration file to keep it simple. Next thing, is to decide what to use as the key. Since messages don’t have type, we should select something that uniquely maps them to destination. Let’s assume that per our requirements it’s a input file name, although it can be anything inside message content. The destination will be expressed as complete URL, i.e. [protocol]://[path]/[fileName], for example ftp://myserver/files/dest.dat. So, the map entry can look like this: <add key=”emp.dat” value=file://myserver/incoming/employees.dat />. I use .dat extension in the example just to emphasize it’s applicable to anyfiles andnot only XML ones.
Once these questions have been answered, the orchestration comes together fairly quickly. On the global level it has one input port, expression to read routing configuration, Decide shape to branch on routing availability condition, and dynamic send port. Receive shape receives input message of XmlDocument type. Output message of the same type is sent through dynamic send port after routing address and all properties have been set:
Inside Decide_IfRoutingAvailable shape there are two branches of execution.If routing address is found thenit will read destination URL from the configuration and select transport protocol. Otherwise, destination will be set to the backup location from configuration file in order for the message to be preserved:
Once protocol is identified, we can create output message and set its properties and destination address. In case if protocol is not supported, we route message to the backup location using the same dynamic send port. That’s how it looks inside Choose Protocole decide shape:
Let’s dive into ConstructFtpMessage shape, to see how properties set:
msgOutput = msgInput;
msgOutput(FTP.UserName) = System.Configuration.ConfigurationManager.AppSettings[“FTPUserName”];
msgOutput(FTP.Password) = System.Configuration.ConfigurationManager.AppSettings[“FTPPassword”];
msgOutput(FTP.PassiveMode) = System.Convert.ToBoolean(System.Configuration.ConfigurationManager.AppSettings[“FTPMode”]);
msgOutput(FTP.RepresentationType) = System.Configuration.ConfigurationManager.AppSettings[“FTPRepresentationType”];
msgOutput(FTP.BeforePut) = System.Configuration.ConfigurationManager.AppSettings[“FTPBeforePut_” + receivedFileName.ToUpper()];
msgOutput(FTP.CommandLogFileName) = System.Configuration.ConfigurationManager.AppSettings[“FTPCommandLog”];
First line simply copies our generic input message content to the output message. Susequent lines set FTP properties from configuration file. Then, all that left is to set destination URL on dynamic port and send output message through it:
DestinationSendPort(Microsoft.XLANGs.BaseTypes.Address) = destUrl.ToString();
As the result, wehave a single orchestration that can handle hundreds of different message schemas and multiple protocols. Anotherpositive outcome isthat deployment greatly simplified.Theapplicationhas one orchestration,two ports, but only one of them is bound at deployment time. Also, noteno schemas, no maps at this time, we will add them later when weaugment application with content transformation functionality.