Over on the BizTalk Gurus Forums, Richard Wallace asked for opinions on best practice for central business logic that would span over a number of BizTalk applications. One of his suggestions was to use .Net assemblies that contained this business logic, however he was concerned about the re-build / re-deploy tax that this would introduce into his BizTalk projects if he needed to change his business logic assemblies.
In my reply I suggested that he looked at assembly redirection, which allows developers to redirect one version of an assembly to another, through changes to an executable’s .config file – in our case, btsntsvc.exe.config. Having never done this in anger in BizTalk, I though this would be a good opportunity for a blog post – here are my findings.
Configuration Changes
To enable assembly redirection, the following lines need to be added to the runtime/assemblyBinding element in the .config file
1: <runtime>
2: <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
3: <dependentAssembly>
4: <assemblyIdentity name="BizTalkAssemblyRedirectionHelper" publicKeyToken="5cce5ee5c1d7dc25" culture="neutral" />
5: <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" />
6: </dependentAssembly>
7: </assemblyBinding>
8: </runtime>
On line 4, we identify the assembly we wish to redirect; on line 5 we identify the new version. If we had wanted, we could specify a range of ‘old’ assemblies that are to be redirected, as follows:
1: <bindingRedirect oldVersion="1.0.0.0-1.2.0.0" newVersion="2.0.0.0"/>
Restart the Host Instance/s for the redirect to take effect. If the new version of the assembly cannot be found in the GAC, you will only see an error when the CLR attempts to load the assembly at runtime, not when the Host Instance restarts, the error is a usual favourite:
Error details: Object reference not set to an instance of an object.
Testing Redirection: Orchestrations & Maps
To test the redirection, I created an orchestration and map that invoked simple helper classes contained within a separate assembly. The helper classes expose a single method which takes two strings as input parameters and returns a concatenation of the these two parameters – an example of the version 2.0 code can be seen below. Versions 1.0.0.0 and 2.0.0.0 were deployed to the GAC.
1: using System;
2: using System.Diagnostics;
3:
4: namespace BizTalkAssemblyRedirectionHelper
5: {
6: [Serializable]
7: public static class RedirectionHelper
8: {
9: public static string ConcatHelper(string a, string b)
10: {
11: Trace.WriteLine("RedirectionHelper - Orchestration, version 2.0.0.0");
12: return (a + b);
13: }
14: }
15:
16: public class RedirectionMapHelper
17: {
18: public string ConcatMapHelper(string a, string b)
19: {
20: Trace.WriteLine("RedirectionHelper - Map, version 2.0.0.0");
21: return (a + b);
22: }
23: }
24: }
Four messages were submitted into BizTalk; in-between the second and third messages, the assembly redirection code was enabled to point to version 2 of the assembly and the Host Instance restarted. The results of the test can be seen in the DebugView screenshot below – once the redirection config change is applied, both the Map and Orchestration start to use the version 2 of the assembly:
Conclusions
A few conclusions can be drawn from this test:
- Assembly redirection can be used within BizTalk for helper classes in both Orchestrations and Maps (on ports & in orchestrations). There are other cases I can think of, such as pipeline components, for example.
- The signatures of these helper methods must remain the same between releases.
- There is a possible issue with build and revision numbers as highlighted by Richard Hallgren in BizTalk assembly version redirection.