It’s been a long while since I wrote something meaningful about programming anything. The last few entries are mostly rants and complaints that probably gives an impression that I stopped programming altogether. On the contrary, I actually still do a lot of programming, it’s just that the code I write is pretty much plain-vanilla and is not even worth mentioning in a conversation with a fellow BizTalk developer…let alone a blog that anyone else can read.
Anyhoo…before I bore my three readers to death with nonsense. I present my proudest contribution to the world of BizTalk programming: REAL Dynamic BizTalk Mapping/Transform. Why do I have to stress out that REAL part? Well, let me give you a background on this…
Prior to BizTalk 2004, Maps (Transform Objects) are hosted in an IIS server and BizTalk pulls the Transform object at runtime. This sucks because you need IIS..but it rules at the same time because you don’t need to recompile everytime you need changes to your map.
Now, fast-forward to today’s BizTalk: I guess some numbnut over at Microsoft thought it was a good idea to “compile” the map into your BizTalk assembly. Sure, it was a good idea in the sense that mapping is a *little* bit faster since it’s binary and running on CLR blah blah blah…at the expense of flexibility: You need to re-compile and re-deploy your freaking BizTalk application if you want to make a change in your map.
I use external XSLTs on my BizTalk map, and it’s a good thing BizTalk allowed us to do so instead of using that atrocious BizTalk mapping tool. Even with that option, BizTalk *still* compiles the external XSLT into the map!
A lot of attempts have been made to bring back this concept of “dynamic maps” but each attempt I saw was lame and/or introduces complexities that I’d rather not deal with: This usually involves the use of custom pipelines that inflexible or using Orchestrations that incurs an unnecessary overhead.
We have a BizTalk Map. Wouldn’t it be great if we can contain our customizations there? This way, We can use it in an orchestration, Receive location, AND send ports just like a “regular” BizTalk map. Well, my friends, you’re in luck. I believe I have found the holy grail of Dynamic biztalk Transforms in BT2006!
Basically, this “special map” will obviously not contain the reference to your external XSLT; it will only contain a n XSLT that references a custom assembly that dynamically loads your actual external XSLT! What this means that even if you change your XSLT, you don’t need to recompile your BizTalk assembly! How cool is that?!
This first link is the XSLT that calls the dynamic XSLT loader, along with the external object XML which defines the location of the dynamic XSLT loader assembly. You create your BizTalk map as usual, then at the properties reference “Custom Extension XML” and “Custom XSL Path” respectively.
The third link is an implementation of the XSLT loader. This loader is pretty basic, but I isolated the interface that does the actual loading called IDynamicMapLoader. You just need to create a regular .NET Assembly, sign it and load in the GAC. I’m not going to expound on what the C# library does since this ain’t .NET Programming 101 Blog. Although I just need to point out the XML that it loads to reference the actual XSLT: maplookups.xml. Here is where you define your XSLT key and the corresponding URI location of the YOUR XSL that will “dynamically” change at runtime.
if you look at DynamicMap.xsl:
<xsl:variable name=”dynamic-map-result” xmlns:DynamicMap=”http://ap.org/BizTalk/DynamicMap” select=”DynamicMap:Transform(’default’, $xml-doc)” />
the ‘default’ is the same key that is in:
<Map Name=”default” Uri=”c:\eai\components\default.xsl” />
That means that in this DynamicMap call, it loads “c:\eai\components\default.xsl” AT RUNTIME. I can change my default.xsl anytime without having the need to recompile the BizTalk assembly!
Of course, the downside is it reads the XSL everytime the map is executed, and this is where your creativity comes in: You just need to write your own implementation of IDynamicMapLoader to make it faster and/or more efficient without sacrificing the main feature: DYNAMIC TRANSFORMS!
I actually wrote a better implementation of IDynamicMapLoader but that’s beyond the scope of what I want to share here (here’s a hint: I used Enterprise Library Caching Block)…
I just showed you the door, it’s up to you to walk through it.
Dynamic Map XSLT
External Extension XML
Dynamic Loader class
MapLookups XML
Oh, make sure that the External Extension XML has the correct PublicKeyToken (i.e., has the public key of the digital signature you sign the Dynamic Loader class assembly with)