使用 Blazor WASM 评估并运行脚本

dev*_*r82 5 c# blazor blazor-client-side blazor-webassembly

我有一个代码可以在服务器上按预期工作,动态生成 C# 代码然后运行它。要运行代码,我使用以下命令:

string assemblyPath = Path.GetDirectoryName(typeof(object).Assembly.Location);
MetadataReference[] references = new MetadataReference[]
{
    MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
    MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location),
    MetadataReference.CreateFromFile(typeof(RunResult).Assembly.Location),
    MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.Console.dll")),
    MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.Runtime.dll")),
    MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.Runtime.Extensions.dll")),
    MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.Collections.dll")),
    MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.Text.Json.dll"))
};

var f =
    await CSharpScript.Create(
            code: code,
            options: ScriptOptions.Default.WithReferences(references))
        .ContinueWith<Func<RunResult, bool>>("new EvaluatorClass().Run")
        .CreateDelegate()
        .Invoke();

await using (MemoryStream ms = new MemoryStream())
{
    await using (StreamWriter currentOut = new StreamWriter(ms) { AutoFlush = true })
    {
        var runResult = f(codeResult);
    }
}
Run Code Online (Sandbox Code Playgroud)

我已将此代码编写为 .NET 标准库的一部分,现在我想使用 Blazor WebAssembly 在客户端运行此代码。

当我调试时,我发现问题是string assemblyPath = Path.GetDirectoryName(typeof(object).Assembly.Location);返回 null,因此不可能(据我所知)包含正在执行的代码所需的引用。

有没有其他方法可以实现这一点,以便它可以在 Blazor 上运行?

JHB*_*ius 0

您可以尝试推断引用,而不是加载文件吗?

var scriptOptions = ScriptOptions.Default;
scriptOptions = scriptOptions.AddReferences(
    typeof(System.Object).GetTypeInfo().Assembly,
    typeof(System.Linq.Enumerable).GetTypeInfo().Assembly,
    /* don't know where `RunResult` comes from, add it yourself */);
scriptOptions = scriptOptions.AddImports(
    "System.Console",
    "System.Runtime",
    "System.Runtime.Extensions",
    "System.Collections",
    "System.Text.Json");

var f =
    await CSharpScript.Create(
            code: code,
            options: scriptOptions)
        [...etc...]
Run Code Online (Sandbox Code Playgroud)

编辑:我已经在scriptOptions = scriptOptions.[...]符号中进行了编辑。我不明白,但这似乎是人们在网上做的方式......这对我来说似乎是错误的。edit2:好的,发现它ScriptOption似乎在内部使用不可变的数据结构。因此调用将(可能)返回一个新对象。