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

Blazor WASM中如何从内部Assembly获取MetadataReference?

在Blazor WASM中使用Roslyn创建MetadataReference的解决方案

在Blazor WASM环境中,由于程序集仅加载在内存中、无物理文件路径,常规的MetadataReference创建方法会失效。以下是两种可行的解决方案:

方案一:将基础程序集作为嵌入式资源打包

步骤

  1. 从本地.NET SDK路径中找到所需的核心程序集(例如System.Private.CoreLib.dll,对应object所在的程序集),路径示例:C:\Program Files\dotnet\shared\Microsoft.NETCore.App\7.0.x\System.Private.CoreLib.dll(根据你的.NET版本调整)。
  2. 将该dll添加到Blazor WASM项目中,右键文件→属性,设置生成操作为「嵌入式资源」。
  3. 通过程序集读取嵌入式资源流,创建MetadataReference。

代码示例

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using System.Reflection;

var currentAssembly = typeof(Program).Assembly;
// 替换为你的嵌入式资源全名,格式为「项目命名空间.文件名」
using var coreLibStream = currentAssembly.GetManifestResourceStream("YourProjectNamespace.System.Private.CoreLib.dll");
if (coreLibStream == null)
{
    throw new InvalidOperationException("未找到嵌入式资源中的核心程序集");
}

var coreLibReference = MetadataReference.CreateFromStream(coreLibStream);

// 构建编译
var syntaxTree = CSharpSyntaxTree.ParseText("public class Test { }", new CSharpParseOptions(LanguageVersion.Preview));
var compilation = CSharpCompilation.Create(
    assemblyName: "MyTestAssembly",
    syntaxTrees: new[] { syntaxTree },
    references: new[] { coreLibReference },
    options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, concurrentBuild: false)
);

using var ms = new MemoryStream();
var emitResult = compilation.Emit(ms);

// 处理编译结果
if (!emitResult.Success)
{
    foreach (var error in emitResult.Diagnostics.Where(d => d.Severity >= DiagnosticSeverity.Error))
    {
        Console.WriteLine($"编译错误:{error.GetMessage()}");
    }
}

方案二:通过HttpClient从服务器下载程序集

步骤

  1. 将所需的dll(如System.Private.CoreLib.dll)复制到Blazor WASM项目的wwwroot目录下。
  2. 注入HttpClient,下载程序集流并创建MetadataReference。

代码示例

@inject HttpClient Http
@using Microsoft.CodeAnalysis
@using Microsoft.CodeAnalysis.CSharp

// 在方法中执行
using var coreLibStream = await Http.GetStreamAsync("System.Private.CoreLib.dll");
var coreLibReference = MetadataReference.CreateFromStream(coreLibStream);

// 后续编译代码与方案一一致

为什么常规方法失效?

  • Blazor WASM运行在浏览器沙箱中,程序集仅加载在内存,无物理文件路径,因此Assembly.Location为空。
  • 反射获取GetRawData/GetRawBytes的私有方法在新版.NET中已被移除。
  • BinaryFormatter在Blazor WASM中被禁用且已弃用,无法序列化程序集。
  • MetadataReference.CreateFromAssembly底层依赖程序集物理路径,因此无法工作。

注意事项

  • 确保引用的dll版本与Blazor WASM项目使用的.NET版本完全一致,避免版本兼容问题。
  • 若需要引用更多程序集(如System.dll),可重复上述方法添加对应资源或文件。
  • 嵌入式资源会增加项目打包体积,若仅需核心类型,引用System.Private.CoreLib.dll即可覆盖object、string等基础类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 03:31:06