Flylib.com

Books Software

 
 
 

- page 43


Summary

Application domains are often described as subprocesses because they provide an isolation boundary around a grouping of assemblies in a process. If the code running in the application domain is verifiably type safe, the isolation provided by the domain is roughly equivalent to that provided by a process in Win32. Application domains also provide the ability to unload code from a running process dynamically. As the author of an extensible application, one of the key decisions you'll make is how to partition your process into multiple application domains. The key is to use application domains to achieve the isolation you want while minimizing the amount of communication between domains because of the cost associated with remote calls.

When writing an extensible application, you'll likely want to take advantage of a new concept in .NET Framework version 2.0 called an application domain manager. Providing an application domain manager is an easy way to implement the host runtime design pattern because the CLR automatically creates an instance of your domain manager in every application domain. Also, if you're writing a CLR host, an application domain manager is the mechanism you use to call into managed code from the unmanaged portion of your host.


Chapter 6. Configuring Application Domains

In Chapter 5, I describe application domains as a construct used to isolate groups of assemblies that are loaded into the same process. An important aspect of this isolation is the ability for the creator of an application domain to be able to constrain various aspects of how the domain operates. For example, a domain's creator must be able to limit the locations from which unsigned assemblies can be loaded into the domain. Other examples include the ability to control how version policy applies to assemblies in the domain and to specify the configuration file where application-specific settings can be stored. These aspects of application domain behavior, along with many others, can be customized through various settings specified when the domain is created. In this chapter, I describe how you can use these settings to customize the behavior of application domains to fit your particular scenario.

Application domain managers also play a key role in your ability to customize how application domains are created in the process. Recall from the previous chapter that an instance of your application domain manager is created by the CLR in every application domain. As part of this process, the CLR calls your application domain manager both before and after a new domain has been created to give you a chance to configure it. This detail is important because it gives you, the author of an extensible application, the ability to decide how all domains are created in the process, including those created by any add-ins you have loaded, not just the ones you create yourself. After I describe the full set of application domain configuration settings, I explain your domain manager's role in customizing how application domains are created in a process.


Application Domain Configuration Settings

The complete list of application domain configuration settings is shown here. These settings are manipulated programmatically through public properties on the System.AppDomainSetup object.

ApplicationBase

PrivateBinPath

DisallowApplicationBaseProbing

PrivateBinPathProbe

DisallowPublisherPolicy

DisallowBindingRedirects

ConfigurationFile

LicenseFile

AppDomainInitializer

ConfigurationBytes

ShadowCopyFiles

ShadowCopyDirectories

CachePath

DynamicBase

ApplicationName

LoaderOptimization

DisallowCodeDownload

ActivationArguments

AppDomainInitializerArguments

The ConfigurationBytes "property" is actually implemented by two methods : GetConfigurationBytes and SetConfigurationBytes .

Before discussing how to use AppDomainSetup , take a look at the general categories of settings you can apply to an application domain:

  • Private assembly location settings These settings are used to specify the root directory (and the structure of its subdirectories) in which the CLR will look for assemblies considered private to a particular application domain. The settings in this category are represented by the ApplicationBase, PrivateBinPath, DisallowApplicationBaseProbing , and PrivateBinPathProbe properties on System.AppDomainSetup .

  • Application-specific configuration settings Applications written in managed code use configuration files to store their settings. These settings can be custom settings defined by the application, or they can be settings that are known to the CLR, such as version policy statements and remote call configuration. Configuration files are associated with an application domain using either the ConfigurationFile or the ConfigurationBytes property on System.AppDomainSetup . The ability to scope an application's configuration data to the domain in which it is running is an essential part of the isolation provided by application domains.

  • Shadow copy settings The CLR includes a feature called shadow copy that you can use to build applications that can be updated dynamically. Shadow copy works by leaving an assembly's files unlocked when they are loaded from disk. In this way, the files can be replaced and reloaded without having to shut down and restart the process. The properties used to set up the shadow copy feature are ShadowCopyFiles, ShadowCopyDirectories, CachePath , and ApplicationName .

  • Assembly version binding settings This group of settings enables you to customize how different aspects of the version policy system apply to code running in an application domain. Specifically, you can prevent from having any effect the version policy statements made either by the application or the publisher of a shared assembly. These customizations are specified using the DisallowPublisherPolicy and DisallowBindingRedirects properties on System.AppDomainSetup .

  • Miscellaneous settings There are a few settings that don't fit directly into the preceding categories. These settings are used to indicate whether code should be loaded into the application domain as domain neutral, to specify whether code running in the domain can dynamically download other code, and so on. The settings in this category are LicenseFile, LoaderOptimization, DynamicBase, DisallowCodeDownload, ActivationArguments, AppDomainInitializer, and AppDomainInitializerArguments .

Typically, the settings used to configure an application domain are specified when the domain is created. This is done by creating a new instance of System.AppDomainSetup , providing values for the properties you're interested in, and passing the new instance to the System.AppDomain.CreateDomain method. For example, the following code specifies the base directory in which the CLR will search for private assemblies for the new domain:

using System;

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

Any time after the domain has been created, you can retrieve the current settings by obtaining an instance of AppDomainSetup using the SetupInformation property of System.AppDomain . For example, the following code prints the application root directory for the application domain running on the current thread:

using System;

   AppDomainSetup adSetup = Thread.GetDomain().SetupInformation;

   Console.WriteLine("The application base directory for the current
                      Domain is: " + adSetup.ApplicationBase);

Accessing Configuration Properties Using System.AppDomain

Using AppDomain.SetupInformation is the preferred way of accessing the application domain configuration settings. However, a few of the individual settings can also be obtained directly from properties on System.AppDomain . The following table describes these properties and their AppDomainSetup equivalents.

System.AppDomain Property

System.AppDomainSetup Equivalent

BaseDirectory

ApplicationBase

RelativeSearchPath

PrivateBinPath

ShadowCopyFiles

ShadowCopyFiles


It might seem odd that only a few of the configuration settings are exposed directly on System.AppDomain . The reason for this situation is primarily historical. The first several iterations of the AppDomain class contained just a few configurable settings, so it made perfect sense to expose them directly as properties on AppDomain . However, as time passed and the number of settings grew, it became convenient to wrap them all in the AppDomainSetup class. Unfortunately, by that time a few of the initial public betas had been released, and the CLR team decided to keep the original properties on System.AppDomain for compatibility reasons.


As I explained earlier, you typically specify the configuration settings for an application domain when you create the domain. However, System.AppDomain exposes public methods that enable you to change the value of a small number of these settings after the domain has been created. If you use these methods to change domain settings, you must do so before any assemblies are loaded into the domain. Calling them later will have no effect. The settings that can be changed through properties on AppDomain , along with the corresponding properties on AppDomainSetup they affect, are shown in Table 6-1.

Table 6-1. Application Domain Settings Exposed by System.AppDomain

System.AppDomain Property

System.AppDomainSetup Equivalent

AppendPrivatePath

PrivateBinPath

ClearPrivatePath

PrivateBinPath

ClearShadowCopyPath

ShadowCopyDirectories

SetCachePath

CachePath

SetDynamicBase

DynamicBase

SetShadowCopyFiles

ShadowCopyFiles

SetShadowCopyPath

ShadowCopyDirectories


{% if main.adsdop %}{% include 'adsenceinline.tpl' %}{% endif %}

I describe how to use these methods in the following sections, where their matching AppDomainSetup property is described.

Now that I've provided an overview of each of the settings, let's dig into the details of how you can use the AppDomainSetup properties to customize the application domains you create.