Learn the AppDomain in. NET and the. NETAppDomain.
What is AppDomain?
AppDomain is a logical container of a group of assemblies. AppDomain is designed to provide isolation. It provides isolation for protecting, configuring, and terminating each of these applications
AppDomain functions:
1. Objects in one AppDomain cannot directly access objects in another Appdomain
After the code in an AppDomain creates an object, the object is owned by the AppDomain that is created. the lifetime of the object cannot exceed the AppDomain that owns the object. To access the object in another AppDomain
Only semantics transmitted by reference or by value can be used. This forces the establishment of clear separation and boundary. This isolation means that the AppDomain can be easily detached from the process without affecting other running AppDomains.
2. AppDomain can be uninstalled
CLR does not support detaching a specific Assembly from the AppDomain. However, the CLR can be told to uninstall an AppDomain to uninstall all the Assembly contained in the AppDomain.
3. AppDomain can be separately protected
After the AppDomain is created, a permission set is applied, which determines the maximum permission to run code in this AppDomain.
4. AppDomain can be configured
After the AppDomain is created, a group of configurations are associated. These configurations mainly affect the AppDomain Assembly Loading Method.
How to access objects across AppDomain?
One AppDomain must communicate with the types and objects in the other AppDomain only through a well-defined mechanism.
The following code creates an AppDomain, loads an assembly, and constructs an instance of the Assembly-defined type. Demonstrate the following three types of behavior during construction:
"By Reference to mail" (Marshal-By-Reference) type, "By Value mail" type (Marshal-By-Value) and type that cannot be sent at all
Class Program {static void Main (string [] args) {var a = Thread. getDomain (); string callingDomianName = Thread. getDomain (). friendlyName; AppDomain a2 = AppDomain. createDomain ("a2"); string exeAssembly = Assembly. getEntryAssembly (). fullName; // Demo1 *** use Marshal-by-reference for cross-origin communication *** Console. writeLine ("{0} # Demo1", Environment. newLine); MarshalByRefType mbrt = null; mbrt = (MarshalByRefType) a2.CreateInstanceAndUnwrap (exeAssembly, "success"); // proves that a reference Console of a proxy object is obtained. writeLine ("agent = {0}", RemotingServices. isTransparentProxy (mbrt); // It looks like calling a method on MarshalByRefType is actually not // we call the method on the proxy type, the proxy enables the application to switch to the AppDomian that actually owns the object // and calls the mbrt method on the real object. someMethod (); // uninstall the new AppDomain. unload (a2); try {// mbrt references a valid proxy object. The proxy object references an invalid AppDomain mbrt. someMethod (); Console. writeLine ("successful call");} catch (AppDomainUnloadedException) {Console. writeLine ("Call failed");} // *** Demo2: Use Marshal-By-Value to perform cross-AppDomain communication Console. writeLine ("{0} # Demo2", Environment. newLine); a2 = AppDomain. createDomain ("a2"); mbrt = (MarshalByRefType) a2.CreateInstanceAndUnwrap. methodWithReturn (); // proves that the Console is not referenced to the proxy object. writeLine ("agent = {0}", RemotingServices. isTransparentProxy (mbvt); // it seems that the method is called in MarshalByValType. In fact, this is also the case of mbvt. toString (); // uninstall the new Appdomain AppDomain. unload (a2); try {// we call a method on the object and will not throw an exception mbvt. toString (); Console. writeLine ("successful call");} catch (AppDomainUnloadedException) {Console. writeLine ("failed to call");} // *** Demo3: Use a non-deliverable type for cross-AppDomain communication Console. writeLine ("{0} # Demo3", Environment. newLine); a2 = AppDomain. createDomain ("a2"); mbrt = (MarshalByRefType) a2.CreateInstanceAndUnwrap (exeAssembly, "failed"); // returns an undeliverable object and throws an exception try {NonMashalbleType nmt = mbrt. methodArgAndReturn (callingDomianName);} catch (AppDomainUnloadedException ex) {Console. writeLine (ex. message);} Console. readKey () ;}} [Serializable] public sealed class externalbyreftype: externalbyrefobject {public externalbyreftype () {Console. writeLine ("the {0} constructor runs in {1}", this. getType (). toString (), Thread. getDomain (). friendlyName);} public void SomeMethod () {Console. writeLine ("executed in {0}", Thread. getDomain (). friendlyName);} public externalbyvaltype MethodWithReturn () {Console. writeLine ("executed in {0}", Thread. getDomain (). friendlyName); financialbyvaltype t = new externalbyvaltype (); return t;} public NonMashalbleType MethodArgAndReturn (string callingThreadName) {Console. writeLine ("calls from {0}", callingThreadName); NonMashalbleType t = new NonMashalbleType (); return t ;}} [Serializable] public sealed class externalbyvaltype: object {private DateTime m_time = DateTime. now; public parameters albyvaltype () {Console. writeLine ("{0} constructor runs in {1}, created in {2: D}", this. getType (). toString (), Thread. getDomain (). friendlyName, m_time);} public override string ToString () {return m_time.ToLongDateString () ;}// the type of public sealed class NonMashalbleType {public NonMashalbleType () {Console. writeLine ("executed in {0}", Thread. getDomain (). friendlyName );}}
The following is the code running result: