C # dynamic code compilation, dynamic execution, and dynamic debugging
Author: eaglet
A few days ago, I saw an article about. NET Dynamic Compiling. Net, which was very enlightening. On this basis, I made some encapsulation to make the call simpler and added support for dynamic code debugging. The support for compiling the same code only once, and the code changes will be automatically re-compiled, automatic loading and manual loading of code reference files.
For example, the class csharpprovider I encapsulate is very simple. The following describes the usage of some public members.
Public attributes
Assemblyfilename: This attribute specifies the name of the accessory generated after dynamic compilation.
Compilerparameters: This attribute specifies the compilation parameters.
References: This attribute specifies the reference in the compiled code. The caller only needs to call references. Add ("XXX. dll") to add his/her own references. For all references in the system namespace, the class is automatically loaded without manual addition. If you do not manually specify the referenced file for your own components, the class automatically guesses Based on the name and space name.
Sourcecodefileencoding: If it is compiled as a file, specify the encoding type of the file.
Common Methods
Public bool compile (string code)
Enter the code string and compile it.
Public bool compilefromfile (string sourcecodefilename)
Compile the input code file
Public object createinstance (string code, string typefullname)
Create a class instance
As shown in the following code, you can enter createinstance (Code, "myinterface. ihelloworld") or createinstance (Code, "helloworld ").
Type name to automatically find and instantiate a qualified class. If the Code contains multiple classes of the specified type, the first class is instantiated.
Using system;
Using myinterface;
[Serializable]
Public class helloworld: marshalbyrefobject, ihelloworld
{
Public String say ()
{
Return "hi ";
}
}
It should be noted that because the appdomain Remote Call is used, all Dynamically Loaded code must inherit from marshallbyrefobject
If it is declared as [serializable] only, it can also be executed, but the main application domain records a reference of the sub-application domain, resulting in the sub-Application
After the domain is detached, the memory cannot be completely released, causing memory leakage. Therefore, this is critical and must be noted.
Public object createinstancefromfile (string filename, string typefullname)
Create a dynamic instance from a file
Next we will talk about debugging dynamic code.
If the dynamically created Code cannot be debugged, it is like a black box, which seriously damages the maintainability of the system. To implement this function in the future, we need to do the following,
First, debugging information should be generated during compilation. This can be achieved by setting compilerparameters. includebuginformation = true;
Second, we must tell the corresponding location of the debugger source code. for the compilation of the source code file, the location of the source code file will be automatically written into the debugging information file *. in PDB, but for memory compilation, I have not found the specified method. If any of you know, please kindly advise. Therefore, to debug dynamic code, you must compile it from a file, that is, callCompilefromfile,Createinstancefromfile.
Third, we need to set a breakpoint in the Code. This can be solved by adding system. Diagnostics. Debugger. Break (); to the code.
As shown in, dynamic code can now be debugged.
Application domain
To avoid Memory leakage, this program encapsulates the use of application domains. Callers do not need to care about the calling and uninstalling processes of application domains. This program in
Re-compilation or object destruction will automatically uninstall the application domain to release the memory. Because this program has encountered a lot of trouble in the application domain
I feel it is necessary to briefly talk about the application domain.
As shown in, the application is a bit like a separate process, but the process runs in the current process. Of course, this metaphor is not appropriate.
Calling an application domain is similar to calling an object in remoting mode between processes. That is to say, the default application domain needs to call objects in other application domains,
You must use a remote call method instead of calling it directly. If you call it directly, the default application domain records a memory reference of the called application domain,
Even after the unload method is run on this application domain, the memory still cannot be released, which is also the biggest problem I encountered when operating the application domain at the beginning.
In addition, all classes exposed between two application domains must be based on marshalbyrefobject, which is very important; otherwise, the memory cannot be released.
Some defects of this program
1. There is no interface for compiling multiple files. In fact, it is very easy to implement. Considering that the code script used for dynamic execution is often relatively simple, it is too lazy to do so.
2. I have not provided an enumeration interface for multiple objects in dynamic code. I will try again later.
Source code download location
Source code download