写在前面
本文采用动态编译的方式,对目标文件code.txt中的C#代码进行实时编译并调用;当然也可以直接在代码中直接装配或读取已有的代码文本,动态编译可以用于很多需要热更新的场景,实现无需重启程序也能达到更新代码的需求。
代码实现
static void Main(string[] args)
{
CSharpCodeProvider objCSharpCodePrivoder = new CSharpCodeProvider();
ICodeCompiler objICodeCompiler = objCSharpCodePrivoder.CreateCompiler();
CompilerParameters objCompilerParameters = new CompilerParameters();
//添加需要引用的dll
objCompilerParameters.ReferencedAssemblies.Add("System.dll");
objCompilerParameters.ReferencedAssemblies.Add("System.Data.dll");
//是否生成可执行文件
objCompilerParameters.GenerateExecutable = false;
//是否生成在内存中
objCompilerParameters.GenerateInMemory = true;
// 读取代码
var code = File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "code.txt"));
//编译代码
CompilerResults cr = objICodeCompiler.CompileAssemblyFromSource(objCompilerParameters, code);
if (cr.Errors.HasErrors)
{
var msg = string.Join(Environment.NewLine, cr.Errors.Cast<CompilerError>().Select(err => err.ErrorText));
Console.WriteLine(msg, "编译错误");
}
else
{
Assembly objAssembly = cr.CompiledAssembly;
object objHelloWorld = objAssembly.CreateInstance("Test");
MethodInfo objMI = objHelloWorld.GetType().GetMethod("Hello");
objMI.Invoke(objHelloWorld, null);
}
Console.WriteLine("Ok");
Console.ReadLine();
}
目标代码:code.txt
using System;
public class Test
{
public void Hello()
{
Console.WriteLine("Hello rjcql");
}
}