Assembly ProcessorArchitecture and Binding Policy

By now we know assemblies compiled with .Net 2.0 will have ProcessorArchitecture.

 

And we know from Josh's blog, that applications with processorArchitecture MSIL will run as 64 bit processes on 64 bit OS. And of course they will run as 32 bit processes on 32 bit OS.

 

If my MSIL application depends on a platform specific assembly MyAssembly, how do I issue binding policy for MyAssembly?

 

Let's discuss app.config and publisher policy separately.

 

App.Config

 

There are two scenarios you may encounter.

 

1. The 32 bit assembly and the 64 bit assembly are always serviced synchronously. This means, the two assemblies will always have the same version number. And the serviced assemblies will also have the same version number. In this case, you can have the same binding policy applying to both the 32 bit assembly and the 64 bit assembly, depending on which platform your application is running.

 

2. The 32 bit assembly and the 64 bit assembly are serviced differently. This means the serviced assemblies may have different assembly version number. In this case, you want different binding policies for 32 bit assembly and 64 bit assembly.

 

To answer the two scenarios above, we introduce a new attribute "processorArchitecture" in assemblyIdentity element for App.config. If processorArchitecture attribute in present in the assemblyIdentity element, we will apply the binding policy only for the assembly with the corresponding processorArchitecture. If the processorArchitecture is not present, we will apply the binding policy to all processorArchitectures.

 

In our example, for the first case, you will have the following app.config:

 

<configuration>

<runtime>

<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

<dependentAssembly>

<assemblyIdentity name="myAssembly"

publicKeyToken="32ab4ba45e0a69a1"

culture="neutral" />

<bindingRedirect oldVersion=”1.0.0.0” newVersion=”2.0.0.0” />

</dependentAssembly>

</assemblyBinding>

</runtime>

</configuration>

 

And for the second case, you will have the following app.config:

 

<configuration>

<runtime>

<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

<dependentAssembly>

<assemblyIdentity name="myAssembly"

publicKeyToken="32ab4ba45e0a69a1"

culture="neutral"

processorArchitecture="x86" />

<bindingRedirect oldVersion= "1.0.0.0” newVersion=”2.0.0.0” />

</dependentAssembly>

<dependentAssembly>

<assemblyIdentity name="myAssembly"

publicKeyToken="32ab4ba45e0a69a1"

culture="neutral"

processorArchitecture="ia64" />

<bindingRedirect oldVersion=”1.0.0.0” newVersion=”3.0.0.0” />

</dependentAssembly>

</assemblyBinding>

</runtime>

</configuration>

 

 

For the second app.config example, if your application is running on x86 platform, the policy statement with processorArchitecture="ia64" will be ignored. Vice versa.

 

The processorArchitecture attribute can only be assigned to a set of pre-defined value, namely, "x86", "amd64", "msil", and "ia64" . The values are case-insensitive. If the attribute is assigned to anything other than one of the four above, the full policy statement will be ignored.

 

You can also have multiple policy statements in the same config file, one with processorArchitecture, and one without. The policy statement with processorArchitecture specified will be consulted first if it is relevant in the platform, then the policy without processorArchitecture.

 

Publiser Policy

 

Publisher Policy is very different from app.config. Publisher Policy has to be carried with a publisher policy assembly. The publisher policy assembly has to be installed to GAC to be effective.

 

Because publisher policy is meant to service one assembly only, we made the decision that publisher policy assembly has to match the processorArchitecture of the assembly that it services. This means, if your assembly is of processorArchitecture MSIL, your publisher policy assembly for that assembly must be also of processorArchitecture MSIL. And the same rule applies to other processorArchitecture. If you have multiple assemblies with different processorArchitectures, you have to ship the same amount of publisher policy assemblies to service them.

 

[update 02/15/2005, add example and emphasize on this is how you issue publisher policy for .Net framework 2.0]

For example, if your assembly has processor architecture of x86, you will use the following command to create a publisher policy for it:

al /link:pub.config /out:policy.1.0.myAssembly.dll /keyfile:sgKey.snk /platform:x86

Remember, this is how you will issue publisher policy in .Net framework 2.0. It is different from .Net framework 1.0/1.1!!!

Another alternative solution is that we always require publisher policy assembly to be of processorArchitecture MSIL, and use the same technique as app.config to service assemblies with different processorArchitectures differently. But this solution may surprise you in an unexpected way. Say you are on IA64, your assembly is IA64. Your publisher policy does not specify processorArchitecture attribute. The publisher policy applies to your IA64 assembly. Perfect. Now someone installs your corresponding x86 assembly. Suddenly the publisher policy meant only for IA64 assembly applies to the x86 assembly automatically. This is totally unexpected. You can argue that the publisher policy should have processorArchitecture specified. But then when you add the x86 assembly, how do you service it? You have to change the same publisher policy that affects IA64 assembly. Now you need to be really careful about what policy statements you put in the policy. It becomes messy quickly.

 

In the end, we decided to take the first approach, that each assembly (with different processorArchitecture) gets their own publisher policy assembly. The rule is much simpler. And it gives you lots of flexibility on how to service assemblies with different processorArchitecture.

 

A side effect of this rule is that you can't change the assembly's processorArchitecture, while expected it to be serviced by publisher policy (The change usually will happen from MSIL to x86/ia64/amd64). If you really need to change the processorArchitecture, you need to change the major/minor assembly version number so that you can service them with totally different publisher policy.

 

And another side effect, that you need to use v1.x toolset to create publisher policy assemblies for v1.x assemblies. Since v1.x assemblies do not have processorArchitecture, their corresponding publisher policy assemblies can't have processorArchitecture either. I don't know if v2.x toolset can create assemblies without processorArchitecture or not.