Using Application Domains
An application domain is a logical container in a single process. Application domains can host multiple assemblies, and they are preventing these assemblies to access the memory of assemblies belonging to other application domains. Even better, when an unhandled exception occurs in a given application domain, that won’t affect the other application domains.
But the benefits aren’t over yet. You can assign different security access levels to each application domain in a given process. Be aware of that when your application runs with full trust, application domains cannot guarantee security, because they can easily bypassed then.
The best example for an application domain ASP.NET. You can assign all of your web sites to a single process (w3wp.exe), and each website will run within its own application domain, isolating themselves from the others.
Application domain related classes are living in the System namespace. The most important is the AppDomain class, which expose the following members:
- ActivationContext: gets the activation context.
- ApplicationIdentity: gets the identity of the application
- ApplicationTrust: gets information describing the permissions granted to an application.
- BaseDirectory: gets the base directory which the assembly resolver uses to probe for assemblies.
- CurrentDomain: static property, gets the current domain for the current thread.
- DomainManager: gets the domain manager.
- Evidence: gets the Evidence associated with the given application domain.
- FriendlyName: gets the friendly name of the application domain.
- Id: the integer representing the number of the application domain in the given process.
- SetupInformation: gets the application domain configuration information.
- ShadowCopyFiles: gets the information if all assemblies loaded into the current domain are shadow copied.
And now the methods of AppDomain:
- ApplyPolicy: returns the assembly name after a policy has been applied.
- CreateComInstanceFrom: creates a new instance of a COM type.
- CreateDomain: static method for creating application domains.
- CreateInstance: creates a new instance of a type from a specified assembly.
- CreateInstanceAndUnwrap: creates an instance of a type from a specified assembly.
- CreateInstanceFrom: creates an instance from a specified assembly. Accepts the file path for the assembly.
- DefineDynamicAssembly: defines a dynamic assembly in the current domain.
- DoCallBack: executes code in another application domain identified by the specified delegate.
- ExecuteAssembly: executes the assembly by file name.
- ExecuteAssemblyByName: executes an assembly.
- GetAssemblies: returns the assemblies contained in the application domain.
- GetCurrentThreadId: no comment.
- GetData: gets a custom value previously stored in the application domain, by a string key.
- InitializeLifetimeService: gives the AppDomain infinite lifetime.
- IsDefaultAppDomain: no comment.
- IsFinalizingForUnload: no comment.
- Load: loads an assembly into the domain.
- ReflectionOnlyGetAssemlbies: returns the assemblies contained in the application domain in a reflection-only context.
- SetAppDomainPolicy: sets a security policy to the given application domain.
- SetData: assigns a value to a property, string key, object value.
- Unload: unloads the specified application domain (not a given assembly!).
Creating application domains is easy. Just use the following syntax:
AppDomain myDomain = AppDomain.CreateDomain(“friendlyName”);
To unload the same domain, call the Unload static method specified above. Be aware of that it may throw a CannotUnloadApplicationDomain exception, for example when it’s in the finalizer. You cannot unload the default application domain, too.
To load assemblies, don’t use the Load method, since it is mainly exist for COM interoperability. Simply call the ExecuteAssemlby, or the ExecuteAssemblyByName method to load an assembly into the current domain.
It’s worth mentioning the AppDomainSetup class. It does exactly what its name tells: provides setup information about an application domain. You should pass an instance of this class into the CreateDomain static method of the AppDomain class. Here’s how:
AppDomainSetup ads = new AppDomainSetup();
ads.ConfigurationFile = @”C:\work\appdomains.exe.config”;
AppDomain myDomain = AppDomain.CreateDomain(“myDomain”, null, ads);
You can then retrieve these settings via the SetupInformation property of your application domain.