January 2018 : Instructor-led Online Course in ASP.NET Core 2.0. Conducted by Bipin Joshi. Read more...
Registration for January 2018 batch of ASP.NET Core 2.0 instructor-led online course has already started. Conducted by Bipin Joshi. Register today ! Click here for more details.

Enforce version changes using Pu

Enforce versioning using assembly redirection and publisher policy

Introduction

Recently I encountered a scenario like this:

"I developed a web site few months back using ASP.NET, ADO.NET and MS-Access database. The application was small one and Access is what the client wanted. Naturally I used OleDB data provider to develop a Data Access Layer (DAL). The DAL was also used by few more applications. The client hosted the DAL in Global Assembly Cache (GAC) as it was being shared across many applications. So far so good. Recently they migrated from Access to SQL Server and requested me to provide new version of DAL now using SQL data provider. Doing so was easy but it how all the applications will automatically use the new version? Still worse during migration period two applications were supposed to use the older version and rest all were supposed to use the new version automatically."

Well. The solution that I used was Publisher Policy.

Assembly Binding

As you probably know, by default any client application which is using a shared component tries to use the exact version of the assembly with which it was built. If the version could not be found it throws an exception. This coupling between the client application and a specific version of the assembly is referred as Assembly Binding.

How to change assembly binding?

There are two ways to change the default behavior of the client applications:

  • Using special tags in client configuration file
  • Publisher Policy

In the first way you need to put <assemblyBinding> section in the client application's configuration file. If your client is an EXE application the configuration file will be <exe_name>.exe.config and if your client is a web application it will be web.config. This section allows you to configure something called as "binding redirection". Binding redirection governs where client's referring older versions should be redirected to. Using this approach is good if you want only few client applications to use the new version because it calls for change in each and every client configuration file.

Publisher Policy is a special assembly that specifies the binding redirections. The advantage of publisher policy is that you as a supplier of the assembly will create it and install it on the server once. All the clients requesting older version will automatically get redirected to the new version. You can of course configure a specific client not to use the publisher policy. This approach is best suited for the scenario that I explained above. A word of caution - using publisher policy wrongly can bring back DLL hell. So, use it carefully in your application.

For the sake of completeness we will see both the approaches in action. depending on your scenario you need to decide which one to use.

Binding redirection using configuration files

Have a look at following markup:

<runtime>
<assemblyBinding 
xmlns="xmlns="urn:schemas-
microsoft-com:asm.v1"">
<dependentAssembly>
   <assemblyIdentity name="MyAssembly"
       publicKeyToken="6083A74B29858FF1" />
        <bindingRedirect oldVersion="1.0.0.0"
		newVersion=�1.1.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>

This is the markup that you need to put in client configuration file. Here are the details of various tags:

  • The entire <runtime> section must appear inside <configuration> tag of the configuration file.
  • Inside <runtime> tag there is <dependentAssembly> tag consists one or more <assemblyIdentity> and <bindingRedirect> tags.
  • Each <dependentAssembly> tag represents one assembly that you want to redirect from older version to the newer
  • The <assemblyIdentity> tag specifies details of the assembly such as its name (name) and public key token (publicKeyToken)
  • The <bindingRedirect> tag specifies the older version (oldVersion) that should be redirected to the newer version (newVersion)

Example of using binding redirection via configuration files

You will find a console application called Client1 that initially uses version 1.0 of an assembly called SharedComp.dll. Later it uses the version 1.1 of the same component by specifying the details in the configuration file.

The general steps to be followed are:

  • Create a class library project called SharedComp
  • Create a method called HelloWorld() that returns a string
  • Specify its version number as 1.0 in the assemblyinfo file using <assemblyVersion> attribute
  • Create a string name using SN.EXE tool
  • Sign your class library with the strong name
  • Host the assembly in GAC using GACUTIL.EXE tool
  • Create a console application
  • Refer the assembly and use its HelloWorld() method
  • Now repeat the same steps to create and host version 1.1 and 2.0 of the assembly
  • Run the client without any configuration file
  • Create the configuration file and add the markup as shown above
  • Run the client. Once specifying version as 1.1 and 2.0 and see what happens.

See top of the article for complete source code.

Creating Publisher Policy

We know from our previous discussion that publisher policy is an assembly which contains binding redirections. In order to create publisher policy you need to use AL.EXE command line tool. The syntax is as shown below:

AL.exe 
-link:<mypolicy.config> 
-out:Policy.1.0.sharedcomp.dll 
-keyfile:MyKey.snk

Here,

  • <mypolicy.config> is an XML file containing the same markup as we used in our previous example
  • The resultant publisher policy assembly must be of the form Policy.<major_ver_of_old_assembly>.<minor_ver_of_old_assembly>.
    <assembly_name>.dll
  • The publisher policy is also hosted in GAC and hence needs a strong name key file

Once you are ready with the publisher policy assembly, host it in GAC using GACUTIL.EXE tool. Delete the client application's configuration file and run the client application again. This time the client should take the new version even if there is no client configuration file.

See top of the article for complete source code.

Summary

Versioning and sharing has its own space in component development. .NET provides mush easier deployment through private assemblies but at times you need to use shared assemblies anyways. Especially third party control and component vendors find shared assemblies easy because many times licensing goes by "per web server" basis. The vendor may want to apply patches or improvements to all the existing applications. Assembly redirection and publisher policies can help in such situations.

 


Bipin Joshi is a software consultant, an author and a yoga mentor having 22+ years of experience in software development. He also conducts online courses in ASP.NET MVC / Core and Design Patterns. He is a published author and has authored or co-authored books for Apress and Wrox press. Having embraced the Yoga way of life he also teaches Ajapa Yoga to interested individuals. To know more about him click here.

Get connected : Twitter  Facebook  Google+  LinkedIn

Posted On : 28 August 2005


Tags : .NET Framework Architecture Components