Locating Assemblies

To successfully deploy an application, you need to understand the process by which the CLR locates an assembly. By default, an application specifies an assembly with the same full name that was used when the application was built. You can see what assembly the application is looking for in the manifest of the application assembly. It might look like Listing 6.7.

Listing 6.7. External References to Dependent Assemblies
.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
  .ver 1:0:3300:0
}
.assembly extern FooLib
{
  .publickeytoken = (BA 04 9F 56 C6 30 9B 78 )
  .ver 1:2:697:15012
}

Listing 6.7 shows that this application looks for two assemblies: version 1.0.3300 of mscorlib and version 1.2.697.15012 of FooLib.

Note

If an assembly load fails, an entry is made in a log file. You can use fuslogvw (Assembly Binding Log Viewer) to see the possible causes of an assembly load failure.


The CLR uses the information that is recorded in the manifest to try to locate each assembly that is listed in the manifest. For assemblies that do not have strong names, version information is ignored. The first step in trying to locate an assembly is to examine applicable policy files. The following section enumerates the different policy files that are a part of the .NET Framework; it also moves step-by-step through the assembly load process.

Examining Policy Files

The first step that the runtime takes to locate a particular assembly is to examine the contents of three different policy files: the machine policy, the publisher policy, and the application policy. These files modify the way that the runtime locates a particular assembly. These files all have the same syntax, but they have different priorities when the same information is contained in each. The lowest in priority is the application policy file. The next priority is the publisher policy file, which can override all application policy files. Of highest priority is the machine policy file, which overrides all configurations on the machine.

Each file is an XML configuration file that consists of the following tags:

  • <assemblyBinding>— This tag is a subtag of <runtime> and sits in the hierarchy of tags in the configuration file as follows:

    <configuration>
        <runtime>
            <assemblyBinding>
    

    This tag has a required namespace attribute, so the actual tag looks like this:

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

    It can have the following subtags:

    <dependentAssembly>
    <probing>
    <publisherPolicy>
    
  • <dependentAssembly>— This tag is a subtag of <assemblyBinding>, and one of these tags will be included for each assembly that is described by the policy. The contents of this tag describe the assembly that the policy is about and how the assembly should be handled. It sits in the hierarchy of the configuration as follows:

    <configuration>
        <runtime>
            <assemblyBinding>
                <dependentAssembly>
    

    It has the following subtags:

    <assemblyIdentity>
    <codeBase>
    <bindingRedirect>
    <publisherPolicy>
    
  • <bindingRedirect>— This tag instructs the runtime to redirect one assembly version for another. It sits in the hierarchy of the configuration as follows:

    <configuration>
        <runtime>
            <assemblyBinding>
                <dependentAssembly>
                    <bindingRedirect>
    

    This tag does not have subtags. It has only two required attributes, so this tag looks like this:

    <bindingRedirect oldVersion="a.b.c.d"
                     newVersion="w.x.y.z" />
    

    The oldVersion attribute can also be a range of version numbers.

  • <codeBase>— This tag is where the runtime can find this assembly if it is not on this machine. It sits in the hierarchy of the configuration as follows:

    <configuration>
        <runtime>
            <assemblyBinding>
                <dependentAssembly>
                    <codeBase>
    

    This tag does not have subtags, but it has two required attributes. The format of the tag looks like this:

    <codebase version="a.b.c.d"
              href="url of assembly" />
    

See Listing 6.8 for an example of most of these tags.

Application Policy Files

The runtime checks for an application policy file. An application policy file for client executables resides in the same directory as the executable and has a name that is the same name as the executable application with a .config suffix appended to it. For example, if the application were foo.exe, then the application configuration file would be foo.exe.config.

Publisher Policy Files

The publisher policy file starts out as a file that looks identical to the application policy file. However, to be a publisher policy file, it must be wrapped by an assembly and put in the GAC. When it is wrapped, the file takes on a name of policy.major.minor.assembly.dll. The first part, “policy”, is fixed and must be the word “policy”. The next two parts are the major and minor numbers that correspond to the version of the assembly to which this policy is to apply. The assembly portion is the name of the assembly.

A publisher policy file overrides an application policy file that refers to the same assembly. Normally, a publisher policy is installed as part of an upgrade. If anything goes wrong with the upgrade, then the user can be returned to the last known good configuration with <publisherPolicy apply="yes|no"/> that would be part of an application configuration file. This is known as safe mode. Safe mode can be applied to just one assembly or to all of the assemblies in an application.

Machine Policy Files

Administers use a machine policy file to specify overriding binding policy for the machine.

Note

Machine and application policy files can be directly edited with the .NET Framework Configuration tool. It makes editing these configuration files much easier. Whenever you can, use the .NET Framework Configuration tool instead of hand editing the raw XML files.


Checking to See if the File Has Been Previously Referenced

After examining the policy files, the runtime checks whether the assembly has been loaded. If the assembly has been previously referenced, a cached valued is returned instead of reloading the assembly.

Checking the GAC

The third step that the runtime takes in loading an assembly is examining the GAC. If the assembly has not been previously found, the binding policy files are merged to form a full assembly name that is looked up in the GAC. If a matching assembly is found in the GAC, then it is returned.

Probing for the Assembly

If an assembly still has not been found, then it is not in the GAC. If the assembly is not in the GAC, the runtime probes the path specified in the <codebase> token in the application configuration file.

In the absence of <codebase>, the application directory is probed for the following directories:

[application directory] / [assembly name].dll
[application directory] / [assembly name] / [assembly name].dll

If a culture is specified, the following paths are probed instead:

[application directory] / [culture] / [assembly name].dll
[application directory] / [culture] / [assembly name] / [assembly name].dll

Finally, if a private path is specified via the <probing> element, then each semi-colon separated path is probed, replacing the application directory with the path.

If this fails, then the search for the assembly fails and a System.IO.FileNotFoundException is thrown to indicate the failure.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.224.95.38