Let's first look at several important concepts in .NET: (1) Application domain, represented by AppDomain objects, providing isolation, uninstall, and security boundaries for executive managed code. Multiple application domains can run in a process; however, there is no one-to-one association between the application domain and the thread. Multiple threads can belong to an application domain, although the given thread is not limited to an application domain, but at any given time, the thread is executed in an application domain. The application domain is created by using the CREATEDOMAIN method. AppDomain instances are used to load and execute assemblies. When you no longer use Appdomain, you can uninstall it. The AppDomain implements a set of events that enable the application to respond when loading an assembly, uninstalling an application domain, or an unprocessed exception. (2) The assembly is the generated block of the .NET framework application; the assembly constitutes a basic unit of deployment, version control, reuse, activation range control, and security permissions. The assembly is a collection of types and resources generated for collaborative work, which constitutes a logical function unit. The assembly provides the public language runtime to provide information sets to identify type implementations intend to simplify application deployment and resolve version control issues that may appear in component-based applications MS-Help: //ms.Netframeworksdk. The CHS / CPGUIDENF / HTML / CPCONWHYUSESSEMBLIES.HTM assembly can be static or dynamic. Static assemblies can include .NET framework types (interfaces and classes), and resources of the assembly (bitmap, JPEG files, resource files, etc.). The static assembly is stored on the disk in the PE file format. You can also use the .NET framework to create a dynamic assembly, the dynamic assembly runs directly from memory and is not stored on the disk before execution. You can save them on the disk after executing the dynamic assembly. (3) How to position the assembly assembly to successfully deploy the .NET Framework application, you must understand how the public language runtime is positioned and binding the assembly of the application. By default, the running library tries to bind the original version of the assembly that generates the app. This default behavior can be overwritten by the configuration file settings. When trying to locate the assembly and parse the assembly reference, the public language runtime will perform several steps. Each step is explained in the following sections. When describing how the runtime is positioned, "detection" is usually used; it refers to a set of tested methods used when using the name and regional positioning assembly. (Use the Binding Log Viewer (FusLogvw.exe) contained in the .NET Framework SDK to view the binding information in the log file) When the runault is trying to resolve the reference to another, it will start Locate and bind to the process of the assembly. This reference can be static or dynamic. When generating, the compiler records a static reference in the metadata of the assembly list. Dynamic reference is dynamically constructed by calling various methods, such as system.reflection.Assembly.Load methods. The preferred way to reference the assembly is to use full reference, including assembly names, versions, regional, and public key tags (if present). The run library will use this information to locate the assembly in accordance with the steps described later in this section. Whether the reference is a reference to a static assembly or a reference to the dynamic assembly, the running library uses the same resolution process. The assembly can also be dynamically referenced by providing only some information about the assembly (for example specified only the assembly name) to the calling method. In this case, search assembly is only in the application directory, and other checks are not performed. You can use any method in different loading assemblies (such as system.reflection.Assembly.Load or AppDomain.Load) to partially reference.
If you want to run the library to check the referenced assembly in the global program cache and application directory, you can specify a part reference with the System.Reflection.Assembly.LoadWithPartialName method. For more information on section bindings, see Some assemblies references. Finally, you can use the method such as System.Reflection.Assembly.Load to dynamically reference and only part of the information; then use the
{
Class testclass
{
[Stathread]
Static void main (string [] args)
{
Outuse test = new outuse ();
TEST.OUTPUT ();
Console.readline ();
}
}
Class Outuse
{
Public outuse ()
{
}
Public void output ()
{
Console.writeline ("Test Dy Load Assembly");
}
}
The above compiled success. To dy_loadasse.exe, execute display: Test Dy Load assembly is placed in the same directory in the same directory in the same directory. Document 2: USING SYSTEM;
Using system.reflection;
Namespace USE_DY_LOAD_ASSEMBLY
{
Class Loadexe
{
[Stathread]
Static void main (string [] args)
{
// use the file name to load the assembly in the capital application domain.
AskEMBLY A = askMBLY.LOADFROM ("DY_LOADASSE.EXE");
TYPE [] TYPES2 = a.gettypes ();
Foreach (Type T in Types2)
{
Console.writeline (T.Fullname);
}
// Get the Type to use.
// Type mytype = a.gettype ("outuse"); this is always wrong
TYPE mytype = a.gettype ("DY_LOADASSE.outuse);
Console.writeline (mytype.fullname);
// Get The Method to Call.
MethodInfo mymethod = mytype.getMethod ("OUTPUT");
/// CREATE AN INSTANCE.
Object obj = activator.createInstance (MyTYPE);
/// // execute the adnamethod method.
Mymethod.invoke (OBJ, NULL);
// Execute result is Test Dy Load Assembly
/ / The following is the main method in calling DY_LOADASSE.EXE, an error occurs
// Type mytype = a.gettype ("DY_LOADASSE.TESTCLASS");
// console.writeline (mytype.fullname);
/// Get The Method to Call.
//MethodInfo mymethod = mytype.getMethod ("main");
/// CREATE AN INSTANCE.
// Object obj = activator.createInstance (MyType);
/// // execute the adnamethod method.
// mymethod.invoke (OBJ, NULL);
Console.readline ();
}
}
}
In fact, no matter where you are .EXE or DLL, you can be loaded with custom bindings In addition to implicitly used by the compiler, it is implicitly used to perform advanced bindings (referring to the all-in-Virtual method, interface, etc.), Reflection can also be explicitly used in the code to complete the late binding. The public language runtime supports multiple programming languages, but the binding rules of these languages are different. In the case of early binding, the code generator can fully control this binding. However, when the late binding is performed by reflection, the binding must be controlled with a custom binding. The Binder class provides custom control for members selection and calling. With custom bindings, you can load an assembly at runtime to get information about the type of the program, and then call the method or to access the field or attribute of this type. This method can be used if you don't know the type of object when you compile (for example, when the object type depends on user input). Using system; namespace DY_LOADDLL
{
Public class helloworld
{
// constant hello world string.
Private const string m_helloWorld = "Hello World";
// Default public constructor.
Public HelloWorld ()
{
}
// Print "Hello World" Plus the Passed Text.
Public void printhello (String txt)
{
// output to the console.
Console.writeLine (M_HelloWorld " TX);
}
}
}
Editing Generates DY_LOADDLL.DLL, following Loadexe.exe below the same directory. Using system;
Using system.reflection;
Namespace USE_DY_LOAD_ASSEMBLY
{
Class Loadexe
{
[Stathread]
Static void main (string [] args)
{
// use the file name to load the assembly in the capital application domain.
AskEMBLY A = askMBLY.LOADFROM ("DY_LOADDLL.DLL");
TYPE [] TYPES2 = a.gettypes ();
Foreach (Type T in Types2)
{
Console.writeline (T.Fullname);
}
// Get the Type to use.
// Type mytype = a.gettype (""); this is always wrong because the above DLL added namespace
TYPE mytype = a.gettype ("DY_LOADDLL.HELLOWORLD");
// Type mytype = a.gettype ("HelloWorld");
Console.writeline (mytype.fullname);
/// Get The Method to Call.
MethodInfo PrintMethod = mytype.getMethod ("Printhello");
// Create An Instance of The HelloWorld Class.
Object obj = activator.createInstance (MyTYPE); // Create the args array.
Object [] test = new object [1];
// set the arguments.
TEST [0] = "from csharp late bound";
// Invoke the printhello method.
PrintMethod.invoke (OBJ, TEST);
Console.readline ();
}
}
}
Of course, we can't help but problem, if the method is overloaded, if it is attribute. What should I do? ? / Search-related msdn, ms-help: //MS.VSCC/MS.MSDNVS.2052/cpguide/html/cpcondynamicallyloadingusingtypes.htm#cpcondynamicallyloadingusingtypes ms-help: //MS.VSCC/MS.MSDNVS.2052/cpref/html /frlrfsystemtypeclassinvokemembertopic.htm
Let's take a look at the dynamic method of the general reflection. Find the following example MS-Help: //ms.vscc/ms.msdnvs.2052/cpref/html/frlrfsystemReflectionMethodBaseClassInvoketopic.htm Public Class A {Public Virtual IntMethod ) {RETURN 0;}} public class b {public virtual int method () {return 1;}} class mymethodinfo {public static int main () {console.writeline ("/nreflection.MethodInfo"); a mya = new a (); B myb = new b (); // get the type and methodInfo type mytypea = type.gettype ("a"); methodinfo mymethodinfoa = mytypea.getMethod ("Method"); type mytypeb = type.gettype (" B "); MethodInfo Mymethodinfob = MyTypeb.GetMethod (" method "); // Get and display the Invoke method Console.Write (" / nFirst method - " MyTypea.FullName " returns " Mymethodinfoa.Invoke (MyA, null )))); Console.write ("/ nsecond method -" mytypeb.fullname "returns" mymethodinfob.invoke (myb, null); Return 0;}} The following is the interface query method, instance creation object, then execute Instance objects Using system;
Public interface ipoint
{
// Return Now Class of Shix InterfaceString ReturnNowClass ();
}
The above file was edited to classsuc.cs for classsuc.cs. Using system;
Namespace Classlib1
{
Public Class Class1: iPoint
{
Public class1 ()
{
}
Public String ReturnNowClass ()
{
Return "WECLONE EXECUTE CLASSLIB1 CLASS1";
}
}
}
Add ClassSuc.dll to the above file, Class1 implements the iPoint interface editing file as classlib1.dll useing system;
Namespace Classlib2
{
Public Class Class2: ipoint
{
Public class2 ()
{
}
Public String ReturnNowClass ()
{
Return "Classlib2" "Class2" "Weclone";
}
}
}
Add ClassSuc.dll to the above file, Class2 implements the iPoint interface editing file as classlib2.dll may have been tired of you, you may have to ask, what do you want to say? ? ? ? Note that the above three DLL COPY is here "C: / Test" Using System in the same path;
Using system.reflection;
Class Loadexe
{
[Stathread]
Static void main (string [] args)
{
// use the file name to load the assembly in the capital application domain.
Assembly B;
B = askMBLY.LOADFROM (@ "c: /test/classssuc.dll");
TYPE [] mytypes = B.GETTYPES ();
// SHOW B interface ipoint
Foreach (Type T in Mytypes)
{
Console.writeline (T.Fullname);
}
MethodInfo method = mytypes [0] .getMethod ("ReturnNowClass");
// Get The Method to Call.
Assembly a;
String K = console.readline ();
/ / When input is greater than 10, the method of calling classlib1.dll may call ClassLib2 method.
IF (Convert.Toint32 (K)> 10)
A = askMBLY.LOADFROM (@ "c: /test/classlib1.dll");
Else
a = askMBLY.LOADFROM (@ "c: /test/classlib2.dll");
TYPE [] TYPES = a.gettypes ();
// Show B Classlib1.class1 or Classlib2.class2
FOREACH (Type T in Types)
{
Console.writeline (T.Fullname);
}
// Create An Instance of The HelloWorld Class.
Object obj = activator.createInstance (Types [0]); // Invoke the Method.
Console.writeline (Method.Invoke (Obj, null);
Console.readline ();
}
}
The execution effect is: iPoint, when the input input 13 continues to perform the display classlib1.class1 WECLONE EXECUTE CLASSLIB1 CLASS1 Requires input 5 Continue to show ClassLib2.class2 WECLONE EXECUTE CLASSLIB2 CLASS2 implementation, through the interface dynamically load assembly. Significance: Reflex mechanism Realizes dynamic plugging, only to change the configuration file and XCOPY corresponding components, you can directly customize a specific system disadvantage without compiling: performance shock speed is slow, since it is able to dynamically load the assembly How to display the Uninstall assembly CLR does not support uninstall assemblies but can uninstall all the assemblies contained in AppDomain. AppDomain.unload method Uninstall the specified application domain. I still want to write an article to tell the dynamic assembly but I understand enough, and I feel that it is not big, so I don't want to learn those things (too impetuous performance), so mention here. Dynamic assemblies are compiler or tools to run metadata and msil at runtime, and can generate portable executable (PE) files on disk (unlike the dynamic load assembly above) to define assemblies at runtime, then Run these assemblies and / or save them to disk. Define the modules in the new program set at runtime and run these modules / or save them to disk. Define types at runtime, create these types of instances, and call these types of methods. The method of the assembly --- "Module ---" Type - "instance is described in ms-help: //ms.netframeworksdk.chs/cpguidenf/html/cpConemittingDynamicassemblies.htm ms-help: //ms.vscc/ms. MSDNVS.2052 / CPREF / HTML / FRLRFSYSTEMAPPDOMAINCLASSDEFINEDYNAMICASSEMBLYTOPIC.HTM Thank Bitfan (Digital World) () makes you have such a harvest