[英]What's the best way to load a CSX script from a C# application?
dotnet-script和CSI等工具允許用戶像“腳本”一樣編寫、編譯和運行 C#,而不是將其代碼包含在完整的預編譯項目中。 這些工具非常適合命令行使用,但在將動態 C#“腳本”集成到更大的 C# 應用程序方面並沒有提供太多幫助。
如果我有一個現有的 C# 應用程序希望通過.csx“腳本”將其他類加載到其現有命名空間中,我該怎么做? 可能嗎?
我猜你需要編譯並執行你的 C# 腳本。
根據我的經驗,我通過直接引用Microsoft.CodeAnalysis.CSharp.Scripting
(版本 3.*)來使用 C# 腳本。
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="3.*" />
我建議使用默認編譯選項:
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.Scripting;
// ...
ScriptOptions options = ScriptOptions.Default;
也許將來,您需要將引用的程序集添加到您的腳本編譯中。
所以你需要編譯你的script
(包含在下面代碼中的字符串變量中):
byte[] assemblyBinaryContent;
var roslynScript = CSharpScript.Create(script, options);
var compilation = roslynScript.GetCompilation();
compilation = compilation.WithOptions(compilation.Options
.WithOptimizationLevel(OptimizationLevel.Release)
.WithOutputKind(OutputKind.DynamicallyLinkedLibrary));
using (var assemblyStream = new MemoryStream())
{
var result = compilation.Emit(assemblyStream);
if (!result.Success)
{
var errors = string.Join(Environment.NewLine, result.Diagnostics.Select(x => x));
throw new Exception("Compilation errors: " + Environment.NewLine + errors);
}
assemblyBinaryContent = assemblyStream.ToArray();
}
GC.Collect(); // it allows to force clear compilation stuff.
Assembly assembly = Assembly.Load(assemblyBinaryContent);
var ret = Run(assembly); // see next paragraph
顯然,您需要一個入口點來執行您的腳本。 我發現了這個棘手的解決方案。 有用。
private object Run(Assembly assembly)
{
//Execute the script
var type = assembly.GetType("Submission#0");
var method = type.GetMethod("<Factory>", BindingFlags.Static | BindingFlags.Public);
var retTask = method.Invoke(null, new object[] { new object[2] }) as Task<object>;
return retTask.GetAwaiter().GetResult();
}
我希望它可以幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.