Codebase hint in config files

If your assemblies cannot be found by the standard fusion probing logic, you have two options:

 

1. Hook up AssemblyResolve event.
2. Specify a codebase hint in config files.

 

The syntax for specifying codebase hint in a config file is in MSDN

 

https://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/gngrfCodeBase.asp

 

An example is given in the link above:

 

<configuration>

   <runtime>

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

         <dependentAssembly>

            <assemblyIdentity name="myAssembly"

                              publicKeyToken="32ab4ba45e0a69a1"

                              culture="neutral" />

            <codeBase version="2.0.0.0"

                      href="https://www.litwareinc.com/myAssembly.dll"/>

         </dependentAssembly>

      </assemblyBinding>

   </runtime>

</configuration>

 

The Remarks section of MSDN documentation is remarkably thorough and accurate. The codebase element works differently depending on which config file it is in. The document explains all of them very well. I am really impressed with the documentationJ

 

But of course, some clarification is always good.

 

1. For the runtime to use the <codeBase> setting in a machine configuration file or publisher policy file, the file must also redirect the assembly version (to a different assembly version, added by me).

 

What this says is, when the <codeBase> hint is in publisher policy or in machine config, if there is no assembly version redirection, or assembly redirection does not result in a different assembly version, the codeBase hint will not be honored.

 

So the example above won’t work in machine config. You have to add an assembly version redirect. And the assembly vesion redirect must result in a different assembly version.

 

2. Application configuration files can have a codebase setting without redirecting the assembly version.

 

The restriction above does not apply to app.config. The codebase hint will be honored even if there is no assembly version redirect.

 

3. After determining which assembly version to use, the runtime applies the codebase setting from the file that determines the version.

 

Say you have app.config, publisher policy, machine.config. If we applied the assembly version redirect in machine.config, we will take the codebase hint in machine.config if any. Otherwise, if we applied the assembly version redirect in publisher policy, we will take the codebase hint in publisher policy if any. Otherwise, we will take the codebase hint in app.config.

 

4. If no codebase is indicated, the runtime probes for the assembly in the usual way.

 

If we did not use any codebase hint, we will probe using the standard heuristics. But if we use a codebase hint, we will only probe that location (after GAC, of course), nothing else.

 

5. If the assembly has a strong name, the codebase setting can be anywhere on the local intranet or the Internet. If the assembly is a private assembly, the codebase setting must be a path relative to the application's directory.

 

This is very easy to understand. But I’d like to clarify on relative path.

 

Codebase hint on publisher policy and machine.config must have absolute path. It is meaningless to have a relative codebase path in publisher policy and machine.config. Codebase hint in app.config can be relative, and it is relative to the application base. So if you say <codeBase version="2.0.0.0" href="subdir\myAssembly.dll"/> , it will be expanded to “application base\subdir\myassembly.dll” .

 

6. For assemblies without a strong name, version is ignored and the loader uses the first appearance of <codebase> inside <dependentAssembly>.

 

This is easily understood.

 

7. If there is an entry in the application configuration file that redirects binding to another assembly, the redirection will take precedence even if the assembly version doesn't match the binding request.

 

This one is a little bit confusing. Let me clarify with an example.

 

Say you have the following config file:

 

<configuration>

   <runtime>

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

         <dependentAssembly>

            <assemblyIdentity name="myAssembly"

                              publicKeyToken="32ab4ba45e0a69a1"

                              culture="neutral" />

            <codeBase version="2.0.0.0"

                      href="https://www.litwareinc.com/myAssembly.dll"/>

         </dependentAssembly>

         <dependentAssembly>

            <assemblyIdentity name="myAssembly"

                              publicKeyToken="32ab4ba45e0a69a1"

                              culture="neutral" />

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

         </dependentAssembly>

      </assemblyBinding>

   </runtime>

</configuration>

 

This config file has two dependentAssembly sections on the same assembly. One with bindingRedirect but no codebase hint. One with codebase hint but no bindingRedirect. When you load myAssembly version 2.0.0.0, we will honor the bindingRedirect, and we will not honor the codebase hint.

 

This is the consequence of how we use the config file. We always apply all the binding policies. After that we use the post policy assembly version to locate codebase hint. In the example above, if the version in codebase element is 2.0.0.1 then we will honor the codebase hint. But it is an odd way of issuing config file. You can simply merge them into one dependentAssembly section.

 

Whidbey changes

 

There is a slightly change of behavior for bullet (1) in Whidbey. We will honor the codebase hint in machine.config, even there is no assembly binding redirect, or assembly binding redirect results in the same assembly version. This change is directly influenced by customer request.