Configuration Files

Assembly binding behavior can be configured based on three XML-based files: the application configuration file, the publisher policy configuration file, and the machine configuration file. These files follow the same syntax and provide information such as binding redirects and the location of the code.

Using a file-based configuration mechanism gives tremendous flexibility in terms of customizing an application's or assembly's behavior.

Let's take a look at each of the configuration files.

Application Configuration File

An application configuration file contains settings specific to an application. The name and location of the application configuration file depends on the application's host.

  • Executable-hosted application: These applications generally have an .exe filename extension and can be run, for example, by double-clicking them in the Explorer window. For such an application, the name of the configuration file is the name of the application with a .config extension. For example, the configuration file for MyApp.exe must be named MyApp.exe.config (the name is case-insensitive). The configuration file should stay in the same directory as that of the application.

  • ASP.NET-hosted application: These files are named Web.config. These files can be stored in either the application's root directory or any of its subdirectories. Configuration files in ASP.NET inherit the settings of configuration files in the Uniform Resource Locator (URL) path. For example, if the application is located at www.mycompany.com/abc, then the ASP.NET pages at www.mycompany.com/abc/def/ looks at the configuration settings of abc as well as abc/def directories.

The configuration information is stored in text files as XML files. The root element of the configuration file is <configuration>. At the next level, configuration settings are grouped by their purpose. For example, configuration settings related to the common language runtime are stored under the <runtime> element, as illustrated in the following code:

<?xml version="1.0"?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
       <probing privatePath="MyBin"/>
    </assemblyBinding>
  </runtime>
</configuration>

We came across this example in Chapter 2. The privatePath entry here informs the common language runtime to include MyBin in the search path for locating assemblies for the application. Here, I show you its usage for two frequently used tasks:

  1. Redirect the runtime to use a different assembly version.

  2. Ask the runtime to download an assembly over the network.

Binding Redirection

In our earlier HelloUser example, HelloUser.exe references assembly ConsoleGreeting.dll version 1.2.3.4. Let's say ConsoleGreeting.dll was subsequently upgraded to version 1.2.3.5 (and the old version removed from the system). If HelloUser.exe is executed, an exception of type FileLoadException (namespace System.IO) occurs; the runtime could not find a match for ConsoleGreeting.dll version 1.2.3.4. However, using the bindingRedirect XML tag in HelloUser.exe.config, as shown here, the run-time can be redirected to use the newer version of ConsoleGreeting.dll:

<?xml version="1.0"?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
       <assemblyIdentity name="ConsoleGreeting"
								           publicKeyToken="6083A74B29858FF1" />
								       <bindingRedirect oldVersion="1.2.3.4"
								           newVersion="1.2.3.5" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

This sample can be found on the companion Web site under Project AppConfiguration.

Using such binding redirections, administrators can force an older application to use the newer versions of the referenced assemblies. If the application shows any incompatible behavior, administrators can revert back to the old settings.

Note that binding redirections require the public key token of the assembly. In general, the assembly resolver does not take into account the version number of a referenced assembly unless it is strong-named.

.NET Admin Tool

Although the configuration files can be created manually, the runtime provides a Microsoft Management Console (MMC) snap-in called the .NET Admin Tool (MsCorCfg.msc) that can be used to generate configuration files. Besides managing the assemblies, the tool can also configure assemblies in the GAC. It also serves some other purposes that we will come across in later chapters.


Network Downloading

Using the configuration file, it is also possible to instruct the common language runtime to download an assembly over the network. This is done using the codeBase tag in the configuration file. The following configuration, for example, downloads ConsoleGreeting.dll version 1.2.3.4 from an HTTP site (Project CodebaseConfiguration).

<?xml version="1.0"?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
       <assemblyIdentity name="ConsoleGreeting"
								publicKeyToken="6083A74B29858FF1" />
								       <codeBase version="1.2.3.4"
								href="http://mycompany.com/MyTest/ConsoleGreeting.dll"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

When the application is run, assembly ConsoleGreeting.dll is downloaded and installed in the download cache. Recall that you can view the download cache either from the Windows Explorer or by running the command gacutil.exe -ldl.

You may also wish to clear the download cache if need be (using the command gacutil.exe –cdl). As long as the codeBase entry for a referenced assembly is present in the configuration file, the assembly automatically gets downloaded again whenever the corresponding application tries to use it.

For other possibilities with the configuration files and for the XML format specification for the configuration file, consult the SDK documentation.

Programmatic Download

It is also possible to download an assembly programmatically. The trick is to use the method Assembly.LoadFrom and to specify the URL path as the argument. This is illustrated in the following code excerpt:

// Project CodebaseConfiguration

class MyApp {
    static void Main(string[] args) {
      Assembly a = Assembly.LoadFrom(
        "http://localhost/MyTest/ConsoleGreeting.dll");
      Console.WriteLine(a.FullName);
    }
}

Publisher Policy Configuration File

Publisher policy files are typically distributed by assembly's publishers (vendors). It is the way the vendor of a shared assembly makes a compatibility statement about a particular version of assembly he or she is releasing. The configuration specified in the publisher policy affects all applications that use the shared assembly.

The publisher policy is most commonly used when a vendor ships a maintenance release; that is, a newer revision of the shared assembly that contains individual bug fixes.

The publisher policy file is an XML-based file with a format similar to that of the application configuration file. As a matter of fact, the application configuration file that we used earlier for redirecting version 1.2.3.4 of ConsoleGreeting.dll to version 1.2.3.5 can be used as a publisher policy file.

Although the policy can be defined in an XML format, the policy file itself cannot be consumed directly for publishing the policy. The vendor has to create an assembly that links the policy file using the Assembly Linker (al.exe) tool. The name of the assembly is required to begin with Policy.<major version>.<minor version> where <major version> and <minor version> correspond to the major and minor version of the shared assembly this policy assembly will be applied to. For example, the following command line creates a policy assembly Policy.1.2.ConsoleGreeting.dll that can be applied to the shared assembly ConsoleGreeting.dll version 1.2.x.x. Here, the policy file is assumed to be ConsoleGreeting.cfg:

al.exe –link:ConsoleGreeting.cfg
–out:Policy.1.2.ConsoleGreeting.dll –keyfile:MyKey.snk

Note that the assembly needs to be signed with a strong-named key pair (MyKey.snk). The .NET Framework requires that the policy assembly be signed with the same strong-named key pair as the original assembly. This ensures that the policy assembly comes from the same vendor that shipped the original assembly.

To apply this publisher policy to a machine, the policy assembly has to be registered in the GAC using our familiar tool, gacutil.exe, as shown here:

gacutil.exe –i Policy.1.2.ConsoleGreeting.dll

The sample code for publisher policy can be found on the companion Web site (project PublisherPolicy).

You may be wondering why the policy assemblies are tied to the major and minor versions of the main assembly. This certainly looks like a restriction as you will need to define a new policy assembly by major and minor version. Deciding on the version number granularity was a challenge for Microsoft. At one extreme, you could require a policy assembly for every assembly version. This would become unmanageable, as the number of policy assemblies would be horrendous. At the other extreme, you could have just one policy assembly for all versions of an assembly, but then expressing compatibility rules for all versions in just one file would get unwieldy. Microsoft decided to go with the middle ground. Moreover, this strategy fits well in the real world. Vendors typically do not change the major and minor versions of an assembly when shipping a maintenance release of an assembly.

Safe Mode

It is possible for an application to run into problems (e.g., DLL hell) because of a publisher policy being in use. To turn the publisher policy off for the specific application, you can set the apply attribute to no for the publisherPolicy XML element in the application configuration file, as shown here:

<?xml version="1.0"?>
<configuration>
   <runtime>
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
       <publisherPolicy apply="no"/>
     </assemblyBinding>
   </runtime>
</configuration>

Turning the publisher policy off using the application configuration file is referred to as the safe mode operation.

It is also possible to finely control the safety level for each individual dependent assembly. You can set the apply tag (on the publisherPolicy element) to either yes or no for each individual dependent assembly, as shown in the following example:

<?xml version="1.0"?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
       <assemblyIdentity name="ConsoleGreeting"
								publicKeyToken="6083A74B29858FF1" />
								       <publisherPolicy apply="no" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

Machine Configuration File

The machine configuration file contains settings that apply to all the applications on the machine. This file, named Machine.Config, resides in the Config subdirectory of the common language runtime's root directory. The format of this file is similar to that of the application configuration file.

When executing an application, the common language runtime first reads the machine configuration file and then reads the application-specific configuration file. This makes it possible to override machine-wide settings for a specific application.

Although the machine configuration file can be edited manually, the preferred way is to use the .NET Admin Tool (MsCorCfg.msc). Figure 3.3 shows a snapshot of the .NET Admin Tool being used to redirect version 1.2.3.4 of ConsoleGreeting.dll to version 1.2.3.5.

Figure 3.3. NET Admin Tool.


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

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