On this basis I do some encapsulation, in order to make the call simpler, and increase the dynamic code debugging support, the same code only compile once support, code changes automatically recompile, code reference file automatic loading and manual loading functions.
As pictured above, the class Csharpprovider I encapsulate is simple, and here's how some of the public members are used.
Public properties
assemblyFileName: This property specifies the name of the accessory that is generated dynamically after compilation.
CompilerParameters: This property specifies the parameters of the compilation
References: This property specifies the reference in the compiled code. The caller can add its own reference as long as it calls References.add ("Xxx.dll"), and the class is automatically loaded for all references to the System namespace, without the need to join manually. For the user's own component, if the reference file is not manually specified, the class is automatically guessed based on the namespace name.
Sourcecodefileencoding: If compiled as a file, specifies the encoding type of the file.
Public methods
public bool Compile (string code)
Enter a code string and compile
public bool Compilefromfile (string sourcecodefilename)
Compiling the input code file
public Object CreateInstance (string code, String typefullname)
To create an instance of a class
As the following code, you can enter CreateInstance (code, "Myinterface.ihelloworld"), you can also enter CreateInstance (code, "HelloWorld"), the program will be based on
Type name to automatically find the class that meets the criteria and instantiate it. If there are multiple classes of the specified type in the code, the first is instantiated.
Copy Code code as follows:
Using System;
Using MyInterface;
[Serializable]
public class Helloworld:marshalbyrefobject, Ihelloworld
{
public string Say ()
{
return "Hi";
}
}
It is important to note here that all dynamically loaded code must inherit from MarshallByRefObject because of the AppDomain remote invocation.
If only declared as [Serializable], it can be executed, but the main application domain records a reference to the application domain, which causes the child application
After the domain is unloaded, memory leaks are still not fully freed. So this is the key, must pay attention to.
Public Object Createinstancefromfile (String fileName, string typefullname)
Create a dynamic instance from a file
Let's talk about debugging the dynamic code
Dynamically created code, if not debugged, is like a black box, which has a greater impact on the maintainability of the system. In the future to achieve this function, we need to do the following work,
First, to generate debugging information at compile time, this can be achieved by setting Compilerparameters.includedebuginformation = true;
Second, we must tell the debugger source corresponding to the location, for files compiled from the situation, the source file location will be automatically written to debug information file *.pdb, and for the case of compiling from memory, I have not found the specified method, if any friend know, also hope enlighten. So at present if you want to debug dynamic code, you must compile from the file, that is, call compilefromfile,createinstancefromfile.
Third, we need to set a breakpoint in the code, which can be added to the Code System.Diagnostics.Debugger.Break (); To solve.
As the following illustration shows, dynamic code can now be debugged.
application domain
To avoid memory leaks, this program encapsulates the use of application domains, and callers do not need to care about the invocation and uninstallation of the application domain. This procedure in
The application domain is automatically unloaded when a recompile or object is destroyed, freeing up memory. Since doing this program is encountering a lot of trouble on the application domain,
It is still necessary to talk about the application domain briefly.
As shown in the figure above, the application is a bit like a separate process, but the process is running in the current process, of course, this metaphor is not appropriate.
A call to an application domain is somewhat similar to a Remoting object invocation between processes, which means that the default application domain calls objects in other application domains.
The method must be invoked remotely, not directly, and if called directly, the default application domain records a memory reference to the invoked application domain.
Even though this application domain performs the Unload method uninstall, memory is still unable to release, which is the biggest trouble I have encountered in the first operation of the application domain.
In addition, all classes exposed to two application domains must be based on MarshalByRefObject, which is important, otherwise it will cause memory to be unable to be freed.
Some flaws in this procedure
1, do not provide the interface to compile multiple files, in fact, to achieve this is very simple, taking into account the dynamic execution of the code script is often relatively simple, so lazy did not do.
2, does not provide an enumeration interface for multiple objects in dynamic code, and then refine it later.
Source Download Address Http://xiazai.jb51.net/200905/yuanma/DynamiclyCompiler.zip