Step 4: Locating the Assembly through Codebases or Probing
After the correct assembly version has been determined by using the information in the calling assembly's reference and in the configuration files, and after it has checked in the global assembly cache (only for strong-named assemblies), the common language runtime attempts to find the assembly. The process of locating an assembly involves the following steps:
If a <codeBase> element is found in the application configuration file, the runtime checks the specified location. If a match is found, that assembly is used and no probing occurs. If the assembly is not found there, the binding request fails.
The runtime then probes for the referenced assembly using the rules specified later in this section.
Note
If you have multiple versions of an assembly in a directory and you want to reference a particular version of that assembly, you must use the <codeBase> element instead of the privatePath attribute of the <probing> element. If you use the <probing> element, the runtime stops probing the first time it finds an assembly that matches the simple assembly name referenced, whether it is a correct match or not. If it is a correct match, that assembly is used. If it is not a correct match, probing stops and binding fails.
Locating the Assembly through Codebases
Codebase information can be provided by using a <codeBase> element in a configuration file. This codebase is always checked before the runtime attempts to probe for the referenced assembly. If a publisher policy file containing the final version redirect also contains a <codeBase> element, that <codeBase> element is the one that is used. For example, if your application configuration file specifies a <codeBase> element, and a publisher policy file that is overriding the application information also specifies a <codeBase> element, the <codeBase> element in the publisher policy file is used.
If no match is found at the location specified by the <codeBase> element, the bind request fails and no further steps are taken. If the runtime determines that an assembly matches the calling assembly's criteria, it uses that assembly. When the file specified by the given <codeBase> element is loaded, the runtime checks to make sure that the name, version, culture, and public key match the calling assembly's reference.
Note
Referenced assemblies outside the application's root directory must have strong names and must either be installed in the global assembly cache or specified using the <codeBase> element.
Locating the Assembly through Probing
If there is no <codeBase> element in the application configuration file, the runtime probes for the assembly using four criteria:
Application base, which is the root location where the application is being executed.
Culture, which is the culture attribute of the assembly being referenced.
Name, which is the name of the referenced assembly.
The privatePath attribute of the <probing> element, which is the user-defined list of subdirectories under the root location. This location can be specified in the application configuration file and in managed code using the AppendPrivatePath property for an application domain. When specified in managed code, the managed code privatePath is probed first, followed by the path specified in the application configuration file.
Probing the Application Base and Culture Directories
The runtime always begins probing in the application's base, which can be either a URL or the application's root directory on a computer. If the referenced assembly is not found in the application base and no culture information is provided, the runtime searches any subdirectories with the assembly name. The directories probed include:
[application base] / [assembly name].dll
[application base] / [assembly name] / [assembly name].dll
If culture information is specified for the referenced assembly, only the following directories are probed:
[application base] / [culture] / [assembly name].dll
[application base] / [culture] / [assembly name] / [assembly name].dll
Probing with the privatePath Attribute
In addition to the culture subdirectories and the subdirectories named for the referenced assembly, the runtime also probes directories specified using the privatePath attribute of the <probing> element. The directories specified using the privatePath attribute must be subdirectories of the application's root directory. The directories probed vary depending on whether culture information is included in the referenced assembly request.
The runtime stops probing the first time it finds an assembly that matches the simple assembly name referenced, whether it is a correct match or not. If it is a correct match, that assembly is used. If it is not a correct match, probing stops and binding fails.
If culture is included, the following directories are probed:
[application base] / [binpath] / [culture] / [assembly name].dll
[application base] / [binpath] / [culture] / [assembly name] / [assembly name].dll
If culture information is not included, the following directories are probed:
[application base] / [binpath] / [assembly name].dll
[application base] / [binpath] / [assembly name] / [assembly name].dll
Probing Examples
Given the following information:
Referenced assembly name: myAssembly
Application root directory: http://www.code.microsoft.com
<probing> element in configuration file specifies: bin
Culture: de
The runtime probes the following URLs:
http://www.code.microsoft.com/de/myAssembly.dll
http://www.code.microsoft.com/de/myAssembly/myAssembly.dll
http://www.code.microsoft.com/bin/de/myAssembly.dll
http://www.code.microsoft.com/bin/de/myAssembly/myAssembly.dll
Multiple Assemblies with the Same Name
The following example shows how to configure multiple assemblies with the same name.
<dependentAssembly>
<assemblyIdentity name="Server" publicKeyToken="c0305c36380ba429" />
<codeBase version="1.0.0.0" href="v1/Server.dll"/>
<codeBase version="2.0.0.0" href="v2/Server.dll"/>
</dependentAssembly>
Other Locations Probed
Assembly location can also be determined using the current binding context. This most often occurs when the Assembly.LoadFrom method is used and in COM interop scenarios. If an assembly uses the LoadFrom method to reference another assembly, the calling assembly's location is considered to be a hint about where to find the referenced assembly. If a match is found, that assembly is loaded. If no match is found, the runtime continues with its search semantics and then queries the Windows Installer to provide the assembly. If no assembly is provided that matches the binding request, an exception is thrown. This exception is a TypeLoadException in managed code if a type was referenced, or a FileNotFoundException if an assembly being loaded was not found.
For example, if Assembly1 references Assembly2 and Assembly1 was downloaded from http://www.code.microsoft.com/utils, that location is considered to be a hint about where to find Assembly2.dll. The runtime then probes for the assembly in http://www.code.microsoft.com/utils/Assembly2.dll and http://www.code.microsoft.com/utils/Assembly2/Assembly2.dll. If Assembly2 is not found at either of those locations, the runtime queries the Windows Installer.
See Also
Concepts
How the Runtime Locates Assemblies
Step 1: Examining the Configuration Files
Step 2: Checking for Previously Referenced Assemblies