Assembly Redirection and SharePoint

1/19/2011


Working on a large development projects in SharePoint 2007, you must have come across the problem which I call
‘mini dll hell’ (Though GAC was provided particularly to overcome this problem of COM). Projects often have the necessity
to release multiple iteration of the core assembly, particularly so if it’s a Product based on SharePoint. There was no easy
way to keep on changing the base assembly’s version and configuring the redirection in the older SharePoint environment
 (though it did exists in .NET). Therefore, it was common for IT professionals to keep notes with the assembly explaining
the change history or in worst case see the metacode with .NET reflector….all this easier said than done.

MOSS 2010 changes this scenario significantly by providing a mechanism to change assembly versions and still be able to
run it in older systems. Let’s take a deep relaxing breath and dive in to the nitty gritty of this…

Example Description

In my example, I have created two projects, a consumer web part and the VersionedAssembly( .dll project) which exposes
function being used by the consuming assembly. First, we will run Versioned Assembly in its base version (1.0). Later we
would modify the version number for VersionedAssembly, incorporate the necessary redirection logic and deploy it to the old
environment… The code for the two assemblies can be found here

1.       Versioned Assembly Project

The Versioned Assembly is a Farm solution (as we want the assembly to be added to GAC). This is done by setting
the Sandboxed Solution to False.

It has one class VersionedAssembly.cs exposing the GetHelloString function. This function will return the version of
the assembly.

public static string GetHelloString()
{
    return "Hello from assembly version : "+ typeof(VersionedClass).AssemblyQualifiedName;
}

The version is mentioned in Properties\AssemblyInfo.cs

[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

2.  Consumer Web Part

This project simply calls the GetHelloString function to return the string on the page via these lines of code

protected override void CreateChildControls()
{

           Label lblTxt = new Label();
           lblTxt.Text = VersionedClass.GetHelloString();
           this.Controls.Add(lblTxt);
}

Note: This solution also has to be a Farm level solution and not a sandbox one.

 Mechanism 

1.       Deploy the Versioned Assembly solution. Make sure to change the Site url as in figure above to reflect the url to
your site collection

 

 After the deployment is complete you shall find the solution under Central Admin > System Settings > Manage Farm solutions.

 2. Deploy the Consumer Assembly web part solution. Make sure to change the Site url as in the figure above to reflect
the url to your site collection. After the deployment is complete you shall find the solution under
Site Collection >Site Settings > Solution (under Galleries).

 3.  Add the consumer web part on the homepage of the site collection as in the figure…



 

 

 4.       Now go ahead and change the version of Versioned Assembly to 2.0 in Assembly.cs file. To enable redirection of
calling assemblies to the new version, open the Package.Template.xml file on the package solution and modify…

<Assembly Location="VersionedAssembly.dll" DeploymentTarget="GlobalAssemblyCache"/>

With

<Assembly Location="VersionedAssembly.dll" DeploymentTarget="GlobalAssemblyCache">
 <BindingRedirects>
  <BindingRedirect OldVersion="1.0.0.0" />
  <BindingRedirects>
<Assembly>

PS: This code is listed in the TextFile1.txt in the project.

Deploy the versioned assembly project and open the home page of the site collection page…
you shall see the versioned 2.0 assembly text listed. 

 

 Behind the hood

Sharepoint writes these binding xml in the web.config file of the web application.
Go to C:\inetpub\wwwroot\sitecollection\web.config , open the file…you will find these lines mentioned

<dependentAssembly>
<assemblyIdentity name="VersionedAssembly" publicKeyToken="192ff5eb4697ab8b" culture="neutral" />
<bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" />
dependentAssembly>

Parting Thoughts

Not all is rosy and world is certainly not perfect. Though the above mentioned process worked flawlessly, keep in
mind that the system would not work if you refer the assembly in the sandbox code or in a timer job. The reason being,
unlike the normal request via web browser, the timer job and the sandbox code works in a different process than wp3.exe.
The process for the timer job is OSTIMER.exe and for the sand box code is SPUCHostService.exe located at \14\UserCode
folder. In case the support for sandbox/timer job is also required, change the config files for each process.

Name

Email

WebSite

Sorry to stick the boot in Akshay - but quite a few inaccuracies and misunderstandings in your article.

#1 Assembly binding redirection is a feature of the .NET framework and is actually nothing to do with SharePoint, 2010 or otherwise.

#2 Its been a part of .NET 1.1 (possibly 1.0?) from at least 2003.

#3 From Parting Thoughts - You can change the binding for all processes using the machine.config file rather then web.config or .config which only apply to a certain site/process.

#4 But the biggie is... all this is just not required for the use you're listing - versioning assemblies.

The recommended method is to keep the AssemblyVersion name fixed and use the FileVersion attribute.

In that way the strong name (how all .net based systems figure out which assembly to use) stays the same but you can tell what version it is (right click properties).

For example if you take Microsfoft.SharePoint.dll - all the different 2010 ones (hotfixes/service packs etc) will use an AssemblyVersion of 14.0.0.0 but the file version will be different.

This article explains more with links to references

stackoverflow.com/questions/1035284/sharepoint-features-how-can-i-use-wildcard-assembly-versioning

including the Microsoft KB556041 - How to use Assembly Version and Assembly File Version support.microsoft.com/kb/556041

Thanks for the comment Ryan.

Yes, I agree with youthat assembly redirection is .NET and not specific to SharePoint . But then SharePoint is nothing more than a ASP.NET application ?

OOB the assembly redirection was not supported by MOSS 2007. It's now fully supported in MOSS 2010 and thats done via this article. Changing machine.config is a possible solution but then you do not want to change it manually everytime there is a new release ...

FileVersion attrbute can used instead, but the problem is if there are two codebases to be maintained for the same assembly in GAC . In that case the only option is Version Attribute change and assembly redirection