This time we’ll combineloosely-typed BizTalk messaging conceptwith dynamicmapping to create generic transformation orchestration.Then we’ll add it to the message broker created in thefirst articleto make it even more powerful.

Quite often message dispatching taskmust be combined with some content adaptation: data mapping, filtering, calculation, etc. Generally, maps are used in BizTalk to achieve that. Since maps are based on source and destination schemas we need to find a way to abstract transformation process from specific schema type to common XmlDocument.What makes it possible is XLANGs transform command. This command accepts output message as argument and uses System.Type ofBizTalk map.It allows usdynamically load and apply any map type to any message type.

First, we have to author schemas and maps. I createdtwo input schemasfor this project: NewEmployee.xsd, NewOrder.xml; two output schemas: Employee.xsd, Order.xsd; and two corresponding maps: NewEmployee_to_Employee, NewOrder_to_Order.I did some changes inDispatchMessage orchestration to integrate with TransformMessage.odx. I added new message variable msgTransformed which isan output from transformation orchestration. Then I simply added Decide shape to check if transformation required for incoming fie. If yes, we pass map key and input message to the TransformMessage.odx using CallOrchestration shape. If no mapping provided then we simply copy incoming message content to msgTransformed:

Again, to retrieve required map name at runtime, we’re going touse the same key-value pairs in the configuration file. In our example we used file name as the key so let’s follow this trend. If we’re gonna store these keys in the same configuration file we need to modify them to keep unique, for example by adding “.MAP” prefix, i.e. <add key=”NewEmployee.xml.MAP” value=”GenericBiztalkPatterns.Maps.NewEmployee_to_Employee” />.

To keep things clean and reusableI factored out mapping functionality in separateTransformMessage.odx. orchestration. This orchestration contains three parameters: msgInput, mapKey, out msgOutput which are self explanatory. Notice, all message parameters are of XmlDocument type again. The orchestration id very simple itself. Read fully qualified map name by passed in key and get Type of this map:

mapTypeQName = System.Configuration.ConfigurationManager.AppSettings[mapKey];
mapType = System.Type.GetType(mapTypeQName);

Then in ConstructMessage shape just apply transformation:

transform(msgOutput) = mapType(msgInput);

That’s how it looks in designer:

I did some changes inDispatchMessage.odx to integrate with TransformMessage.odx. There is new message variable msgTransformed which is going to be an output from transformation. Also, I added Decide shape to check if mapping required. If yes, then input message and map key is passed intoTransformMessage.odx through CallOrchestration shape. Ohterwise, input message simply copied to msgTransformed:

Now, all we need is to make surethere’re proper entries in the configuration file:

<add key=”NewEmployee.xml” value=”file://C:\Projects\Design Patterns\GenericBizTalkPatterns\GenericBizTalkPatterns.MessageBroker\Ports\File.out\employee.xml” />
<add key=”NewEmployee.xml.MAP” value=”GenericBizTalkPatterns.MessageBroker.Maps.NewEmployee_to_Employee, GenericBizTalkPatterns.MessageBroker, Version=1.0.0.0, Culture=neutral, PublicKeyToken=44e796208f4e4812″ />
<add key=”NewOrder.xml” value=”ftp://[Your FTP server path here]/order.xml” />
<add key=”NewOrder.xml.MAP” value=”GenericBizTalkPatterns.MessageBroker.Maps.NewOrder_to_Order, GenericBizTalkPatterns.MessageBroker, Version=1.0.0.0, Culture=neutral, PublicKeyToken=44e796208f4e4812″ />
<add key=”FTPUserName” value=”[Your FTP username]” />
<add key=”FTPPassword” value=”[You FTP password]” />
<add key=”FTPMode” value=”true” />
<add key=”FTPRepresentationType” value=”Binary” />
<add key=”FTPCommandLog” value=”C:\Projects\Design Patterns\GenericBizTalkPatterns\GenericBizTalkPatterns.MessageBroker\ftp.log” />
<add key=”FTPBeforePut_NewOrder.xml” value=”” />
<add key=”NotRoutedDestination” value=”file://C:\Projects\Design Patterns\GenericBizTalkPatterns\GenericBizTalkPatterns.MessageBroker\Ports\backup” />
<add key=”NotSuportedProtocolDestination” value=”file://C:\Projects\Design Patterns\GenericBizTalkPatterns\GenericBizTalkPatterns.MessageBroker\Ports\backup” />

At some point, configuration filecan get quite large, that’s why I prefer to keep group of settings in individual configuration files, like destinations.config, maps.config, etc., but that’s a topic for another article. So far, we’ve seen how generic messaging concept can help creating flexible agile BizTalk applications.