This article was posted on my previous blog located at http://blog.avanadeadvisor.com/blogs/patrick_boom in February. I moved it here.
Assembly redirection, a technique already introduced and available since the first versions of the .NET framework, is in my opinion not widely used in our line of work.
Sure, product suppliers like Microsoft itself use it frequently during updates, but somehow I have not come across this too often in my career.
To explain the concept of assembly redirection is a little bit beyond the scope of this blog, but I would like to elaborate on using this when using it with SharePoint 2007 WSP’s.
In large projects, especially with a lot of users in an already live environment, executing updates on the platform should be done with care and clear preparation. This is even truer when the update at hand involves shared frameworks, which multiple other projects use and you do not have direct control over. Of course, one could update the component without changing its version number and strong name, but this would not be very good practice, as version management and maintenance become much harder, if not impossible. The answer, of course, is assembly redirection.
Assembly redirection involves a technique to forward a particular method call to another assembly at runtime. For example, an application is bound to version 184.108.40.206 of your component. When updating, you increment the version number to 220.127.116.11. When published, the application will still use version 18.104.22.168 of the assembly if it is still available. If not, it will break. Using assembly redirection, you can forward the call to your 22.214.171.124 version and even remove the 126.96.36.199 version. This would automatically upgrade any application that referenced it and in the process, you make sure the latest version is used.
One very important aspect of this method, is that you have to ensure, no guarantee, that you are backwards compatible. Not doing this is bound to introduce problems. Secondly, you should not change the definition of the method in doing something completely different than its original scope, which could lead to unexpected behavior of its clients.
That said, how does this relate to SharePoint 2007? Well, suppose I have a SharePoint middleware layer that executes various common functions, on top of which SharePoint application are build. Using good practice, I publish this layer to the SharePoint platform using a WSP (or multiple), which in turn configures SharePoint (for example the SafeControls) and publishes the assemblies to the Global Assembly Cache. When time passes, I would like to update the framework by introducing new features (which would lead to a version increment) and bug fixes. I would then publish an updated WSP, which will retract the old one (and thus removing the configuration and the assemblies from the GAC) and install the new one. Doing this without assembly redirection will break all applications that reference the assemblies.
Ok, so, just include an assembly redirection policy, you think. That is where the trouble starts. To install an assembly redirection policy in the GAC, you need to convert it into an assembly, as the GAC only accepts assemblies. There are many articles on the internet that describe how to create such an assembly, so I will not go into that here. I use, like many others, WSP Builder (or its Visual Studio Extension) to create my WSP’s. If I include the policy assemblies in the GAC folder, WSP builder will also package that. Well, so far so good. When I install this WSP into SharePoint, it will result in an error, stating that the policy assemblies could not be published into the GAC. This is caused by a simple caveat in using policy assemblies. Because they are not ‘real’ assemblies in the true sense of the word, they are only allowed to be published to the GAC, if the original configuration file that was used to create the assembly, is located in the same directory. And the WSP omits this file. The current version of WSP builder does not include .config files when packaging, even if they are located in the same directory.
There are several ways in solving this problem. You could create your WSP manually, be writing the correct DDL that does includes the config files in the root of the WSP. You could modify WSP builder (as it is open source) to include these config files in the root of the WSP. I however, choose the outside approach. As a WSP is just a cabinet file with a different extension, I created a small app that uses cablib.dll (just like WSP Builder) to modify the created wsp and insert the config files at the root. This has two advantages:
- The config files are only needed during install, so using this method would avoid the config files being included in the manifest.xml and therefore permanently stored on the file system.
- I can choose whether or not to include the config files, or even update them afterwards, without rebuilding the WSP.
After this, the WSP installs just fine and the policy assemblies are included in the GAC, ensuring proper rerouting of method calls to old assemblies, therefore automatically upgrading any dependent applications in the SharePoint landscape.
A couple of final notes on the redirection part:
- Create one policy assembly for each version you wish to reroute. You cannot reroute multiple versions from within a single policy assembly.
- The naming of the policy redirection assembly is very strict and follows naming conventions. Not following these conventions will result in your assembly not being redirected.
- Ensure that you only use the major and minor versions in the AssemblyVersion attribute. Build and revision numbers should never be included in the AssemblyVersion attribute, but in the AssemblyFileVersion attribute. For example:
AssemblyVersion 188.8.131.52, AssemblyFileVersion 1.0.010043.0 (day 43 in the year 2010)
AssemblyVersion 184.108.40.206, AssemblyFileVersion 2.1.010043.1
Assembly references are made using the AssemblyVersion attribute, thus giving you the possibility to publish bug fixes (which only increment the build and revision numbers), without the need for a policy redirection assembly.
Hope this can be of use to you. Let me know your thoughts! Any comments are appreciated.