用 CSharpCompilation 进行动态编译
项目里需要用到动态编译。
网上一大片的介绍C#动态编译的,是 CodeDomProvider,这个东西确实好用。但是说好了支持 .net 6.0 的,但运行时却说不支持当前平台。
一群骗子,你们写文章的时候都不自己验证的吗!
网上找的关于 CSharpCompilation 代码的博文。说得很详细,但是废话太多,他们喜欢把自己的项目中的需求放到功能里,我要读懂代码,还要先把博主的项目需求读懂。但我只需想整明白其中一点功能而已。
经过精简之后,得到如下示例(需要导入两个软件包:Microsoft.CodeAnalysis.CSharp、Microsoft.CodeAnalysis.CSharp.Workspaces)
private string GetCSCode() {
StringBuilder sb = new StringBuilder();
sb.AppendLine("using System;");
sb.AppendLine();
sb.AppendLine("namespace Test {");
sb.AppendLine(" public class Util {");
sb.AppendLine(" public int Add(int a, int b) {");
sb.AppendLine(" return a + b;");
sb.AppendLine(" }");
sb.AppendLine(" }");
sb.AppendLine("}");
sb.AppendLine();
return sb.ToString();
}
public void F2() {
string csCode = this.GetCSCode();
SyntaxTree tree = CSharpSyntaxTree.ParseText(csCode);
var compilation =
CSharpCompilation.Create("Test")
.AddReferences(
MetadataReference.CreateFromFile(
typeof(object).Assembly.Location)
)
.AddSyntaxTrees(tree)
.WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
EmitResult emitResult;
byte[] dllBytes;
using(var stream = new MemoryStream()) {
emitResult = compilation.Emit(stream);
dllBytes = stream.ToArray();
}
if (emitResult.Success) {
// Assembly assembly = Assembly.LoadFrom("d:\\test.dll");
Assembly assembly = Assembly.Load(dllBytes);
var obj = assembly.CreateInstance("Test.Util");
var method = obj.GetType().GetMethod("Add", new Type[] { typeof(int), typeof(int)});
var added = method.Invoke(obj, new object[] { 10, 20 });
Console.WriteLine(added);
}
}
浙公网安备 33010602011771号