Roslyn/CSharpScript-如何保存/加载编译以避免编译等待时间

本文关键字:编译 加载 等待时间 保存 CSharpScript- 何保存 Roslyn | 更新日期: 2023-09-27 18:06:50

我正在尝试将c#脚本集成到我的数据库应用程序中。我使用globals对象使全局变量可以从脚本中访问。

如果是第一次编译脚本,我对等待时间不满意
如何保存和加载编译以避免等待时间?

Script<object> script = CSharpScript.Create(scriptCode, globalsType: typeof(MyGlobals));
script.Compile();   //<-- load the Compilation from database/file here
script.RunAsync(myGlobalsInstance).Wait();

Roslyn/CSharpScript-如何保存/加载编译以避免编译等待时间

您可以创建一个CSharpScript,然后通过GetCompilation获得编译以获得编译。

var script = CSharpScript.Create("script..");
var compilation = script.GetCompilation();

通过编译,您实际上可以将dll和pdb compilation.Emit()复制到磁盘或内存中。棘手的(也是roslyn的内部问题(是,一旦有了程序集,如何获得要执行的代码的委托。你可以在这里看到罗斯林是如何做到的。

如果要预编译,可以使用System.CodeDom.Compiler中的类;

CompilerParameters opts = new CompilerParameters();
opts.OutputAssembly = <Destination FileName>;
opts.ReferencedAssemblies.AddRange(<needed references>);
//set other options;            
var codeProvider = new Microsoft.CSharp.CSharpCodeProvider();
var results = codeProvider.CompileAssemblyFromFile(opts, <Your script source files>);
//check that there's no errors in the results.Errors

现在磁盘上有一个已编译的程序集。您可以动态加载它,从中实例化一个类并执行方法。您应该设计在脚本中运行的代码,使其接受某些配置。你应该采取以下步骤:

var mydll =  AppDomain.CurrentDomain.Load(<compiled Assembly From the previous step>);
    var classInstance =  <YouTypeOrInterface>mydll.CreateInstance(
      <TypeFromTheAssembly>, 
      false, 
      BindingFlags.CreateInstance, 
      null,                                                                
      new object[] { <Arguments you need to provides to your class constructor> },                                                                              CultureInfo.InvariantCulture, null);

现在您可以对这个实例执行您想要的操作。例如classInstance.ExecutSomething(…(