源代码的动态编译问题,我们知道这个可以利用Roslyn来解决。
实现一个编译助手类,它的Compile方法将会对参数sourceCode提供的源代码进行编译。该方法返回源代码动态编译生成的程序集,它的第二个参数代表引用的程序集。
添加Nuget包:
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="3.7.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.7.0" />
编译助手类:
public class Compiler
{
public Assembly Compile(string text, params Assembly[] referencedAssemblies)
{
var references = referencedAssemblies.Select(it => MetadataReference.CreateFromFile(it.Location));
var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);
var assemblyName = "_" + Guid.NewGuid().ToString("D");
var syntaxTrees = new SyntaxTree[] { CSharpSyntaxTree.ParseText(text) };
var compilation = CSharpCompilation.Create(assemblyName, syntaxTrees, references, options);
using (var stream = new MemoryStream())
{
var compilationResult = compilation.Emit(stream);
if (compilationResult.Success)
{
stream.Seek(0, SeekOrigin.Begin);
return Assembly.Load(stream.ToArray());
}
throw new InvalidOperationException("Compilation error");
}
}
}
动态编译:
string code = @"public class Person
{
public static string SayName()=>""fan"";
}";
var compiler = new Compiler();
var assembly = compiler.Compile(code, Assembly.Load(new AssemblyName("System.Runtime")), typeof(object).Assembly);
var personType = assembly.GetType("Person");
if (personType != null)
{
var method = personType.GetMethod("SayName");
var result = method.Invoke(null, null);// fan
}
参考:https://www.cnblogs.com/artech/archive/2020/04/07/dynamic-controllers.html