Application Domain
Summary
Application domains provide a more secure and versatile unit of processing that the common language runtime can use to provide isolation between applications. Application domains are typically created by runtime hosts, which are responsible for bootstrapping the common language runtime before an application is run.
Historically, process boundaries have been used to isolate applications running on the same computer. Each application is loaded into a separate process, which isolates the application from other applications running on the same computer.
Managed code must be passed through a verification process before it can be run (
unless the administrator has granted permission to skip the verification). The verification process determines whether the code can attempt to access invalid memory addresses or perform some other action that could cause the process in which it is running to fail to operate properly. Code that passes the verification test is said to be type-safe. The ability to verify code as type-safe enables the common language runtime to provide as great a level of isolation as the process boundary, at a
much lower performance cost.
Isolating applications is also important for application security. For example, you can run controls from several Web applications in a single browser process in such a way that the controls cannot access each other's data and resources.
The isolation provided by application domains has the following benefits:
- Faults in one application cannot affect other applications. Because type-safe code cannot cause memory faults, using application domains ensures that code running in one domain cannot affect other applications in the process.
- Individual applications can be stopped without stopping the entire process. Using application domains enables you to unload the code running in a single application. (NB You cannot unload individual assemblies or types. Only a complete domain can be unloaded)
- Code running in one application cannot directly access code or resources from another application. The common language runtime enforces this isolation by preventing direct calls between objects in different application domains. Objects that pass between domains are either copied or accessed by proxy. If the object is copied, the call to the object is local. That is, both the caller and the object being referenced are in the same application domain. If the object is accessed through a proxy, the call to the object is remote. In this case, the caller and the object being referenced are in different application domains. Cross-domain calls use the same remote call infrastructure as calls between two processes or between two machines. As such, the metadata for the object being referenced must be available to both application domains to allow the method call to be JIT-compiled properly. If the calling domain does not have access to the metadata for the object being called, the compilation might fail with an exception of type System.IO.FileNotFound. See Accessing Objects in Other Application Domains Using .NET Remoting for more details. The mechanism for determining how objects can be accessed across domains is determined by the object. For more information, see MarshalByRefObject? Class.
- The behavior of code is scoped by the application in which it runs. In other words, the application domain provides configuration settings such as application version policies, the location of any remote assemblies it accesses, and information about where to locate assemblies that are loaded into the domain.
- Permissions granted to code can be controlled by the application domain in which the code is running.
Создание домена приложения
A common language runtime host creates application domains automatically when they are needed. However, you can create your own application domains and load into them those assemblies that you want to manage personally. You can also create application domains from which you execute code.
You create a new application domain using one of the overloaded
CreateDomain
methods in the
System.AppDomain
class. You can give the application domain a name and reference it by that name.
The following example creates a new application domain, assigns it the name
MyDomain
, and then prints the name of the host domain and the newly created child application domain to the console.
using System;
using System.Reflection;
class AppDomain1
{
public static void Main()
{
Console.WriteLine("Creating new AppDomain.");
AppDomain domain = AppDomain.CreateDomain("MyDomain");
Console.WriteLine("Host domain: " + AppDomain.CurrentDomain.FriendlyName);
Console.WriteLine("child domain: " + domain.FriendlyName);
}
}
Выгрузка домена приложения
When you have finished using an application domain, unload it using the
System.AppDomain.Unload
method. The
Unload
method gracefully shuts down the specified application domain. During the unloading process, no new threads can access the application domain, and all application domain–specific data structures are freed.
Assemblies loaded into the application domain are removed and are no longer available. If an assembly in the application domain is domain-neutral, data for the assembly remains in memory until the entire process is shut down. There is no mechanism to unload a domain-neutral assembly other than shutting down the entire process. There are situations where the request to unload an application domain does not work and results in a
CannotUnloadAppDomainException
.
The following example creates a new application domain called
MyDomain
, prints some information to the console, and then unloads the application domain. Note that the code then attempts to print the friendly name of the unloaded application domain to the console. This action generates an exception that is handled by the try/catch statements at the end of the program.
using System;
using System.Reflection;
class AppDomain2
{
public static void Main()
{
Console.WriteLine("Creating new AppDomain.");
AppDomain domain = AppDomain.CreateDomain("MyDomain", null);
Console.WriteLine("Host domain: " + AppDomain.CurrentDomain.FriendlyName);
Console.WriteLine("child domain: " + domain.FriendlyName);
AppDomain.Unload(domain);
try
{
Console.WriteLine();
Console.WriteLine("Host domain: " + AppDomain.CurrentDomain.FriendlyName);
// The following statement creates an exception because the domain no longer exists.
Console.WriteLine("child domain: " + domain.FriendlyName);
}
catch (AppDomainUnloadedException e)
{
Console.WriteLine("The appdomain MyDomain does not exist.");
}
}
}
Настйрока домена приложения
You can provide the common language runtime with configuration information for a new application domain using the
AppDomainSetup
class. When creating your own application domains, the most important property is
ApplicationBase
. The other
AppDomainSetup
properties are used mainly by runtime hosts to configure a particular application domain.
Each instance of an application domain consists of both
System.AppDomain properties
and
AppDomainSetup
information. You can retrieve application domain setup information using the
System.AppDomain
class. You can also query the
AppDomainSetup
object for the application domain to obtain setup information that was passed to the domain when it was created.
The following example creates a new application domain and then prints several member values to the console.
using System;
using System.Reflection;
class AppDomain3
{
public static void Main()
{
//Create the new application domain.
AppDomain domain = AppDomain.CreateDomain("MyDomain", null);
//Output to the console.
Console.WriteLine("Host domain: " + AppDomain.CurrentDomain.FriendlyName);
Console.WriteLine("new domain: " + domain.FriendlyName);
Console.WriteLine("Application base is: " + domain.BaseDirectory);
Console.WriteLine("Relative search path is: " + domain.RelativeSearchPath);
Console.WriteLine("Shadow copy files is set to: " + domain.ShadowCopyFiles);
AppDomain.Unload(domain);
}
}
The following example sets, and then retrieves, setup information for an application domain. Note that
AppDomain.SetupInformation.ApplicationBase
gets the configuration information.
using System;
using System.Reflection;
class AppDomain5
{
public static void Main()
{
// Application domain setup information.
AppDomainSetup domaininfo = new AppDomainSetup();
domaininfo.ApplicationBase = "f:\\work\\development\\latest";
domaininfo.ConfigurationFile = "f:\\work\\development\\latest\\appdomain5.exe.config";
// Creates the application domain.
AppDomain domain = AppDomain.CreateDomain("MyDomain", null, domaininfo);
// Write the application domain information to the console.
Console.WriteLine("Host domain: " + AppDomain.CurrentDomain.FriendlyName);
Console.WriteLine("child domain: " + domain.FriendlyName);
Console.WriteLine();
Console.WriteLine("Application base is: " + domain.SetupInformation.ApplicationBase);
Console.WriteLine("Configuration file is: " + domain.SetupInformation.ConfigurationFile);
// Unloads the application domain.
AppDomain.Unload(domain);
}
}
See also:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconusingapplicationdomains.asp
Загрузка сборок в домен приложения
In the .NET Framework, there are several ways to load an assembly into an application domain. Each way uses a different class.
You can use the following overloaded methods to load an assembly into an application domain:
- The
System.AppDomain
class contains several overloaded Load methods. These methods are primarily used for COM interoperability, although they can be used to successfully load any assembly into the current or a new application domain. You can also load an assembly using the CreateInstance
methods.
- The
System.Reflection.Assembly
class contains two static overloaded methods, Load
and LoadFrom
. The two methods vary by load context.
using System;
using System.Reflection;
public class Asmload0
{
public static void Main ()
{
// Use the file name to load the assembly into the current application domain.
Assembly a = Assembly.LoadFrom("adname.exe");
//Get the type to use.
Type myType = a.GetType("adname");
//Get the method to call.
MethodInfo mymethod = myType.GetMethod("adnamemethod");
//Create an instance.
Object obj = Activator.CreateInstance(myType);
//Execute the adnamemethod method.
mymethod.Invoke(obj,null);
}
}
Получение информации о сборке
The
System.Reflection
namespace contains many methods for obtaining information from an assembly. This section demonstrates one of these methods.
The following example obtains type and member information from an assembly.
using System;
using System.Reflection;
class Asminfo1
{
public static void Main(string[] args)
{
Console.WriteLine ("\nReflection.MemberInfo");
//Get the Type and MemberInfo.
//Insert the fully qualified class name inside the quotation marks in the following statement.
Type MyType =Type.GetType("System.IO.BinaryReader");
MemberInfo[] Mymemberinfoarray = MyType.GetMembers(BindingFlags.Public|BindingFlags.NonPublic|
BindingFlags.Static|BindingFlags.Instance|BindingFlags.DeclaredOnly);
//Get and display the DeclaringType method.
Console.Write("\nThere are {0} documentable members in ", Mymemberinfoarray.Length);
Console.Write("{0}.", MyType.FullName);
foreach (MemberInfo Mymemberinfo in Mymemberinfoarray)
{
Console.Write("\n" + Mymemberinfo.Name);
}
}
}
See also:
Reflection Overview at MSDN
Links
--
AndreyUstyuzhanin - 07 Apr 2004