This article was originally published as ASP.NET Support Voice Support Voice column in September 2004. This is not a standard KB article.
Hello again and welcome to the September '04 edition of the Support Voice Column. I would like to thank Jim Cheshire
, a support engineer here at Microsoft supporting ASP .NET, for his contributions. Jim has great ideas for the Support Voice column and wanted to share them. Look for Jim's contributions over the next few months, and as always, send us your suggestions for future columns. Thank you Jim!
Jim has been working with Microsoft for six years on the FrontPage, VB, and ASP .NET teams. During that time, he has written for the Office Developer Center on MSDN, and he is the author of a book on FrontPage, Special Edition Using Microsoft Office FrontPage 2003
. Jim also has a Web site where he provides free add-ins for FrontPage to enable Web developers to make the most out of Microsoft products. Here is that Web site address:
So please pull up a chair, kick the shoes off, and read through our column all about Using publisher policy assemblies
, and remember, you can submit your ideas to us using the "ASK FOR IT" link included in every column we publish. Jeremy
If you've ever worked with COM components in your Web applications, it is likely that you count yourself among those who celebrated the arrival of the Microsoft .NET Framework and the ease with which you can now update components that your Web application references. In most cases, updating a component is as simple as dropping a new build into the Bin folder or into the Global Assembly Cache (GAC). However, even in the .NET world, it is possible to break assembly binding when you update a component. Fortunately, the .NET Framework provides you with ways that you can control assembly binding. One powerful (and seldom understood) way of harnessing that control is the publisher policy assembly. In this article, I will show you how to use a publisher policy assembly to force your application to bind to a specific version of an assembly that is located in the GAC.
Methods of assembly binding
Before I delve into the specifics of publisher policy assemblies, it's important that you understand the ways that assembly binding can be broken. Every .NET assembly is identified using four characteristics:
- Assembly name
- Major or minor version
- Public key token
If you change one or more of these, the binding for the assembly will be broken. For example, if you reference version 1.0.1 of a component in your Microsoft ASP.NET application, and then recompile the component to version 1.0.2, ASP.NET will automatically use version 1.0.2. However, if you recompile the component to version 1.1.0, ASP.NET will continue to use the 1.0.1 version even though a later version is installed in the GAC because the assembly binding is broken when the minor version of the assembly changes.
In most cases, this is exactly what you want to happen. However, there may be cases where you want to force your ASP.NET application to use a new version even when one of the four identifying characteristics has changed. Suppose, for example, that you are a developer of custom server controls. You have just fixed a few minor bugs in a couple of methods in your server control. You have also added some cool new functions, and you want to make sure that anyone who is using your control in any existing application has access to the new functions. However, because of your implementation of versioning, you incremented the minor build for the assembly. When your control is installed into the GAC on the Web server, ASP.NET applications that were compiled against the original version will not use the new version automatically.
There are a few different ways that you can force your application to use a specific version of an assembly. You can add a binding redirect to a web.config file or to the machine.config file. That will require you to modify a configuration file, which means that you can't simply point server administrators to an installation package for the new version of your component and have existing applications use it automatically. Redirecting using the web.config file has an additional shortcoming in that it requires the developer or administrator to know which applications are using your component so that he or she can update the web.config file. So how can you easily make all existing applications use the new version of your component simply by installing the new version of the component? If your answer is to use a publisher policy assembly, you are exactly right!
What is a publisher policy assembly?
A publisher policy assembly is an assembly that configures the policy to be used when the .NET runtime binds to an assembly. The publisher policy assembly is installed into the GAC and is named using the following naming convention:
refer to the major and minor version of the old version of the assembly. Therefore, if you are updating version 1.0 of Website.dll to version 2.0, and you want all existing applications to bind to the new version, the publisher policy assembly name would be:
After this publisher policy assembly is installed into the GAC, any application that references version 1.0 of Website.dll will bind to version 2.0 of Website.dll instead. At this point, you might be asking how the .NET runtime knows to bind to version 2.0 of Website.dll when it sees the publisher policy assembly in the GAC. The answer lies in the publisher policy file, an XML configuration file that is used to create the publisher policy assembly.
The publisher policy file
The publisher policy file contains the information necessary to redirect the binding from one version of an assembly to a new version. After you've created the publisher policy file, you use the .NET Assembly Linker utility (Al.exe) to create the publisher policy assembly.
Here is an example of a publisher policy file that redirects any reference to version 1.0 of Website.dll to version 2.0. The public key token can be obtained by looking at the properties of the assembly currently installed in the GAC.
<configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="website" publicKeyToken="18517ea673f8584b" culture="neutral" /> <bindingRedirect oldVersion="220.127.116.11" newVersion="18.104.22.168"/> </dependentAssembly> </assemblyBinding> </runtime></configuration>
After you've created the publisher policy file, save it with a .config file extension, for example, website
.config. You then use the Assembly Linker tool to create the publisher policy assembly.
The entire processScenario: You want to ensure that any ASP.NET application currently referencing version 1.0 of your server control uses version 2.0 instead after the updated version is installed. You don't want anyone to have to modify configuration files for this to happen. You have wisely determined that a publisher policy assembly is the way to go.
This is how you should proceed.
- Change the version and recompile. The first step is to create the new version of your component. After you've done that, you will need to modify the version number in the AssemblyInfo file for your component.
- Create the publisher policy file.Create the publisher policy file for the assembly using the format shown above.
- Use Assembly Linker (Al.exe) to create the publisher policy assembly.The Assembly Linker is included with the .NET Framework SDK. To create the publisher policy assembly that redirects a binding from version 1.0 of Website.dll to version 2.0 using a publisher policy file called website.config, run the following command:
This command will create a new assembly called policy.1.0.website.dll. This naming convention is important, as indicated in the "What Is a Publisher Policy Assembly?" section.
al /link:website.config /out:policy.1.0.website.dll /keyfile:c:\keyfile.snk
- Install the publisher policy assembly into the Global Assembly Cache.The publisher policy assembly is installed into the GAC. It will be used by the .NET runtime when any application attempts to bind to version 1.0 of the Website.dll, and it will force the application to bind to the new version automatically.
- Install the new version into the Global Assembly Cache.Install the new version of the component into the GAC. After the new version has been installed, the old version can be safely removed.
- Restart Microsoft Internet Information Services (IIS).The final step is to restart IIS. This is necessary because of the way the .NET runtime binds to an assembly. If the .NET runtime has already bound to a specific assembly, it will reuse that binding. Therefore, for the binding redirect to the new assembly to work, you must restart the worker process.
After completing these steps, any application that was built with a reference to version 1.0 of Website.dll will automatically use version 2.0.Publisher policy assemblies offer a convenient way to ensure that developers have full control over assembly binding. As you've seen in this article, if your goal is to force existing applications to use a new version of your component, a publisher policy assembly provides you with the confidence that applications will always use the version you expect them to use without having to alter any configuration files or rely on manual changes by a server administrator.
Until next time,
Microsoft Developer Support