Blazor WASM中如何从内部Assembly获取MetadataReference?
在Blazor WASM中使用Roslyn创建MetadataReference的解决方案
在Blazor WASM环境中,由于程序集仅加载在内存中、无物理文件路径,常规的MetadataReference创建方法会失效。以下是两种可行的解决方案:
方案一:将基础程序集作为嵌入式资源打包
步骤
- 从本地.NET SDK路径中找到所需的核心程序集(例如
System.Private.CoreLib.dll,对应object所在的程序集),路径示例:C:\Program Files\dotnet\shared\Microsoft.NETCore.App\7.0.x\System.Private.CoreLib.dll(根据你的.NET版本调整)。 - 将该dll添加到Blazor WASM项目中,右键文件→属性,设置生成操作为「嵌入式资源」。
- 通过程序集读取嵌入式资源流,创建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从服务器下载程序集
步骤
- 将所需的dll(如
System.Private.CoreLib.dll)复制到Blazor WASM项目的wwwroot目录下。 - 注入
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
相关产品推荐
相关产品推荐

