You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Blazor WebAssembly中使用Roslyn创建CSharpCompilation?

在Blazor WebAssembly中使用Roslyn创建编译实例的解决方案

核心问题原因

Blazor WASM运行在浏览器的WebAssembly沙箱中,程序集从网络加载至内存,无本地文件路径,因此Assembly.Location始终为空,传统从文件创建MetadataReference的方式完全不适用。

可行解决方案

1. 从程序集内存流创建MetadataReference

你提到的MetadataReference.CreateFromStream()不需要本地路径——可直接从程序集的内存字节流构建引用。.NET 5及以上版本支持Assembly.GetRawBytes()方法直接获取程序集的字节数据,示例代码如下:

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using System.Reflection;
using System.IO;
using System.Collections.Generic;
using System.Linq;

// 收集编译必需的核心程序集
var requiredAssemblies = new[]
{
    typeof(object).Assembly,          // System.Runtime
    typeof(Enumerable).Assembly,      // System.Linq
    typeof(CSharpCompilation).Assembly // Microsoft.CodeAnalysis.CSharp
};

var references = new List<MetadataReference>();
foreach (var assembly in requiredAssemblies)
{
    using var stream = new MemoryStream(assembly.GetRawBytes());
    var reference = MetadataReference.CreateFromStream(stream);
    references.Add(reference);
}

// 构建编译实例
var compilation = CSharpCompilation.Create(
    assemblyName: "DynamicGeneratedAssembly",
    syntaxTrees: new[] { CSharpSyntaxTree.ParseText(userInputCode) },
    references: references,
    options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
);

2. 预打包非核心程序集为嵌入资源

若需引用第三方程序集(如Newtonsoft.Json),可将其作为嵌入资源打包到项目中,再通过资源流构建引用:

  1. 将目标程序集添加到Blazor项目,设置生成操作为嵌入的资源
  2. 通过资源名称读取流并创建引用:
var currentAssembly = Assembly.GetExecutingAssembly();
// 资源名称格式:项目命名空间 + 资源路径(比如你的项目是BlazorCodeEditor,资源放在Resources文件夹下)
var resourceName = "BlazorCodeEditor.Resources.Newtonsoft.Json.dll";

using var stream = currentAssembly.GetManifestResourceStream(resourceName);
if (stream != null)
{
    var reference = MetadataReference.CreateFromStream(stream);
    references.Add(reference);
}

3. 精准控制依赖范围

避免遍历所有加载的程序集(Blazor WASM加载的程序集数量多,会增加内存开销),根据用户输入代码用到的类型,仅添加必需的程序集引用,减少编译负担。

注意事项

  • 沙箱限制:浏览器环境无法访问本地文件系统,所有程序集必须通过内存流或嵌入资源获取
  • 性能优化:Roslyn在浏览器中编译性能有限,尽量简化编译逻辑,避免处理大体积代码
  • 版本兼容:Assembly.GetRawBytes()仅支持.NET 5及以上版本,若使用更早版本,需通过反射或第三方工具获取程序集字节数据

内容的提问来源于stack exchange,提问作者Liam Rougoor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 20:15:40