Application Domains and Assemblies
This topic describes the relationship between application domains and assemblies. You must load an assembly into an application domain before you can execute the code it contains. Running a typical application causes several assemblies to be loaded into an application domain.
The way an assembly is loaded determines whether its just-in-time (JIT) compiled code can be shared by multiple application domains in the process, and whether the assembly can be unloaded from the process.
If an assembly is loaded domain-neutral, all application domains that share the same security grant set can share the same JIT-compiled code, which reduces the memory required by the application. However, the assembly can never be unloaded from the process.
If an assembly is not loaded domain-neutral, it must be JIT-compiled in every application domain in which it is loaded. However, the assembly can be unloaded from the process by unloading all the application domains in which it is loaded.
The runtime host determines whether to load assemblies as domain-neutral when it loads the runtime into a process. For managed applications, apply the LoaderOptimizationAttribute attribute to the entry-point method for the process, and specify a value from the associated LoaderOptimization enumeration. For unmanaged applications that host the common language runtime, specify the appropriate flag when you call the CorBindToRuntimeEx Function method.
There are three options for loading domain-neutral assemblies:
SingleDomain loads no assemblies as domain-neutral, except Mscorlib, which is always loaded domain-neutral. This setting is called single domain because it is commonly used when the host is running only a single application in the process.
MultiDomain loads all assemblies as domain-neutral. Use this setting when there are multiple application domains in the process, all of which run the same code.
MultiDomainHost loads strong-named assemblies as domain-neutral, if they and all their dependencies have been installed in the global assembly cache. Other assemblies are loaded and JIT-compiled separately for each application domain in which they are loaded, and thus can be unloaded from the process. Use this setting when running more than one application in the same process, or if you have a mixture of assemblies that are shared by many application domains and assemblies that need to be unloaded from the process.
JIT-compiled code cannot be shared for assemblies loaded into the load-from context, using the LoadFrom method of the Assembly class, or loaded from images using overloads of the Load method that specify byte arrays.
Assemblies that have been compiled to native code by using the Native Image Generator (Ngen.exe) can be shared between application domains, if they are loaded domain-neutral the first time they are loaded into a process.
JIT-compiled code for the assembly that contains the application entry point is shared only if all its dependencies can be shared.
A domain-neutral assembly can be JIT-compiled more than once. For example, when the security grant sets of two application domains are different, they cannot share the same JIT-compiled code. However, each copy of the JIT-compiled assembly can be shared with other application domains that have the same grant set.
When you decide whether to load assemblies as domain-neutral, you must make a tradeoff between reducing memory use and other performance factors.
Access to static data and methods is slower for domain-neutral assemblies because of the need to isolate assemblies. Each application domain that accesses the assembly must have a separate copy of the static data, to prevent references to objects in static fields from crossing domain boundaries. As a result, the runtime contains additional logic to direct a caller to the appropriate copy of the static data or method. This extra logic slows down the call.
All the dependencies of an assembly must be located and loaded when the assembly is loaded domain-neutral, because a dependency that cannot be loaded domain-neutral prevents the assembly from being loaded domain-neutral.