Private Assembly Directory Settings


If you've written and deployed a managed executable, you've probably deployed that executable and many of the assemblies it depends on to the same directory on disk. Similarly, if you've written a Microsoft ASP.NET application, you've probably deployed the code needed for your application to the bin directory under the site's virtual directory on the Web server. By deploying applications in this way, you're taking advantage of one of the key features of the Microsoft .NET Framework deployment model: the ability to deploy (almost) everything needed to run an application into the same directory. This deployment model has several benefits. It makes your application easier to install, uninstall, or replicate between machines. Furthermore, it enables you as an application developer to have tighter control over the dependencies that your application loads.

The key to providing this private deployment model is the ApplicationBase property on AppDomainSetup. When a host creates an application domain, this property is set to the root directory under which all dependent assemblies will be deployed. For example, the ASP.NET host sets ApplicationBase to the virtual root for the Web site. Similarly, the default CLR host sets the ApplicationBase for an executable to the directory on disk where the executable file is located. The following example sets the ApplicationBase for a new domain to a location in the Program Files directory:

   using System;    AppDomainSetup adSetup = new AppDomainSetup();    adSetup.ApplicationBase = @"c:\Program Files\MyApp";    AppDomain ad = AppDomain.CreateDomain("MyApp", null, adSetup);

Typically, the value of ApplicationBase is set to a fully qualified directory on the same machine on which the host is running. However, because an ApplicationBase can be any directory, you can also set it to a directory on a remote Web or file server. For example, you could set the ApplicationBase for a domain to http://www.cohowinery.com or \\cohowinery\myapp. When doing so, however, keep in mind that the security requirements for code running in the application domain are greater. Specifically, code loaded from a remote location obtains a lower level of trust by default than code running from the local machine.

If you don't provide a value for ApplicationBase when creating a new domain, the CLR will set ApplicationBase to the directory containing the executable file that caused the process to be created. For example, if you launch an executable file from c:\program files\myapp, that directory will be the default ApplicationBase for all domains created in the process.

Customizing the ApplicationBase Directory Structure

Once you've established the root directory for your new application domain, you can customize the subdirectories under the root in which the CLR will look for private assemblies by using the PrivateBinPath, PrivateBinPathProbe, and DisallowApplicationBaseProbing properties on AppDomainSetup.

By default, the CLR will look for dependencies directly in the ApplicationBase and in a subdirectory of the ApplicationBase that matches the simple name of the assembly you are looking for. For example, consider an application myapp.exe that depends on an assembly in the file utils.dll. Myapp.exe is deployed to c:\program files\myapp. When resolving the reference from myapp to utils, the CLR will look for the file utils.dll in the following two directories (in the order shown):

  • c:\program files\myapp

  • c:\program files\myapp\utils

    Note

    The CLR looks in different subdirectories for satellite resource assemblies. Satellite assemblies have a culture as part of their name. In these cases, the CLR looks for the assembly in subdirectories of the ApplicationBase named by culture instead of in the subdirectories in the preceding example. For example, if utils were a satellite resource assembly, requests for the German satellite would cause the CLR to look for utils.dll in the following subdirectories of the ApplicationBase:

    • c:\program files\myapp\de

    • c:\program files\myapp\de\utils


You can change the set of subdirectories the CLR looks in for dependencies by using the PrivateBinPath property on AppDomainSetup. PrivateBinPath is a semicolon-delimited list of subdirectories under the ApplicationBase in which you'd like the CLR to search for dependencies. Keep in mind that all directories specified using PrivateBinPath must be subdirectories of the ApplicationBase. You cannot use this property to cause assemblies to be loaded from outside of the ApplicationBase. Any subdirectories you supply using this property are searched in addition to the subdirectories the CLR would search by default. For example, the following code creates an application domain with an ApplicationBase of c:\program files\myapp and uses PrivateBinPath to add a subdirectory named bin to the list of subdirectories searched:

   AppDomainSetup adSetup = new AppDomainSetup();    adSetup.ApplicationBase = @"c:\Program Files\MyApp";    adSetup.PrivateBinPath = "bin";    AppDomain ad = AppDomain.CreateDomain("one", null, adSetup);

Not only does this code cause the bin subdirectory to be searched, it also causes the CLR to look in subdirectories under bin named by assembly name. That is, the CLR applies the same searching rules to the new bin subdirectory that it applies to the ApplicationBase itself. If myapp.exe were to be run in this domain, the CLR would now look in the following directories for utils.dll (assuming no culture is involved):

  • c:\program files\myapp

  • c:\program files\myapp\utils

  • c:\program files\myapp\bin

  • c:\program files\myapp\bin\utils

There are two other techniques you can use to customize the layout of the directory structure under the ApplicationBase. First, you can specify additional directories to search using settings in an application configuration file. Configuration files are associated with domains by using the ConfigurationFile property on AppDomainSetup as described later in the chapter. You use the <probing/> element with the privatePath attribute to specify additional search directories. The directories you add using the configuration file are searched in addition to the directories specified using the AppDomainSetup.PrivateBinPath property. Here's a simple example of a configuration file that uses privatePath to add the bin directory to the search list:

   <configuration>       <runtime>          <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">             <probing privatePath="bin" />          </assemblyBinding>       </runtime>    </configuration>

For simple configuration files such as this one, editing the Extensible Markup Language (XML) directly using a text editor works great, but in more complex scenarios you might find it more convenient to enter your values for privatePath using the .NET Framework Configuration tool. This tool is available under the Administrative Tools group in the Microsoft Windows control panel. After adding an application to the tool, simply use its Properties dialog box to specify additional search directories. An example of an application's Properties dialog box is shown in Figure 6-1. See the .NET Framework SDK documentation for a complete description of application configuration files and the .NET Framework Configuration tool.

Figure 6-1. Editing settings in an application's Properties dialog box using the .NET Framework Configuration tool


The second alternative to using the PrivateBinPath property to customize the private assembly search list is to use the AppendPrivatePath and ClearPrivatePath methods on System.AppDomain. As their names imply, AppendPrivatePath is used to add additional search directories and ClearPrivatePath sets the search list back to the empty string.

Turning Off ApplicationBase Searching

In some scenarios, you might not want the CLR to look for assemblies in the ApplicationBase directory structure at all. For example, as I discuss in Chapter 8, the CLR hosting APIs enable you to customize the assembly loading process to such an extent that you can define your own assembly storage formats and locations. CLR hosts such as Microsoft SQL Server 2005 use this capability to store and load assemblies out of a relational database instead of from the file system, for example. Because SQL Server 2005 ensures that all application assemblies are loaded out of the database, it doesn't make sense to have the CLR look for assemblies in a directory specified by ApplicationBase. Even if you do rely on the standard file systembased assembly storage, you might have a deployment model in which you want to prevent assemblies from being loaded directly out of your ApplicationBase. ASP.NET is an example of a CLR host that uses such a deployment model. If you've built a Web application using ASP.NET, you probably noticed that you must place the private assemblies for your application in the bin directory under the ApplicationBasethe ApplicationBase itself is never searched.

AppDomainSetup has two properties to support scenarios such as these: DisallowApplicationBaseProbing and PrivateBinPathProbe (easily the most poorly named setting of the bunch). DisallowApplicationBaseProbing is a boolean property you can use to prevent the CLR from looking for assemblies anywhere in the ApplicationBase directory structure. By setting this property to true, the CLR will not look in the ApplicationBase or in any of its subdirectories. The PrivateBinPathProbe property is similar in spirit to DisallowApplicationBaseProbing, but there is one key difference. When PrivateBinPathProbe is set, the ApplicationBase directory is never searched, but all subdirectories are. This is the property that ASP.NET uses to force you to put your private assemblies in the bin subdirectory under the ApplicationBase. PrivateBinPathProbe is not a boolean property, as you'd probably expect. (I know I did.) Instead, PrivateBinPathProbe is a string. By supplying any string whatsoever for this property, you are indicating that only the subdirectories of ApplicationBase should be searchednot the ApplicationBase itself. The following example enables this behavior by setting PrivateBinPathProbe to the string *:

   AppDomainSetup adSetup = new AppDomainSetup();    adSetup.PrivateBinPathProbe = "*";    AppDomain ad = AppDomain.CreateDomain("No AppBase Domain", null, adSetup);



    Customizing the Microsoft  .NET Framework Common Language Runtime
    Customizing the Microsoft .NET Framework Common Language Runtime
    ISBN: 735619883
    EAN: N/A
    Year: 2005
    Pages: 119

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net