.NET Standard 2.0迁移后动态代码编译失败:CodeDom抛出PlatformNotSupportedException
解决.NET Standard 2.0下CodeDom编译动态代码抛出PlatformNotSupportedException的问题
这个问题我之前也踩过坑,核心原因是**CSharpCodeProvider这类CodeDom相关API在.NET Standard/.NET Core环境下是不被官方支持的**——它原本是.NET Framework专属的动态编译方案,虽然.NET Standard 2.0做了部分API兼容,但跨平台场景下的动态编译能力被砍掉了,所以你才会遇到这个平台不支持的异常,和你是否引用netstandard程序集没有关系。
下面是具体的解决办法,改用Roslyn编译器(.NET官方推荐的现代编译方案)来实现动态代码编译:
步骤1:添加Roslyn相关NuGet包
你需要在项目中安装以下两个NuGet包:
Microsoft.CodeAnalysis.CSharpMicrosoft.CodeAnalysis.Common
可以通过NuGet包管理器安装,或者用命令行:
Install-Package Microsoft.CodeAnalysis.CSharp Install-Package Microsoft.CodeAnalysis.Common
步骤2:替换CodeDom代码为Roslyn实现
把你原来的CodeDom代码替换成下面的Roslyn版本,它能在.NET Standard 2.0环境下正常工作:
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using System; using System.Reflection; using System.Text; using System.IO; using System.Linq; // 构建要编译的代码字符串 var className = $"CodeEvaler_{Guid.NewGuid().ToString("N")}"; var sb = new StringBuilder(); sb.Append($@" public class {className} {{ // 这里可以替换成你的动态代码逻辑,示例如下: public string GetDynamicResult() {{ return ""Hello from dynamically compiled code!""; }} }} "); // 配置编译选项:生成类库,开启发布级优化 var compilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary) .WithOptimizationLevel(OptimizationLevel.Release); // 获取动态代码需要的引用程序集 var references = new MetadataReference[] { // 基础类库引用 MetadataReference.CreateFromFile(typeof(object).Assembly.Location), // LINQ相关引用(如果动态代码用到的话) MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location), // netstandard 2.0引用 MetadataReference.CreateFromFile(Assembly.Load("netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51").Location) }; // 创建编译对象 var compilation = CSharpCompilation.Create( assemblyName: className, syntaxTrees: new[] { CSharpSyntaxTree.ParseText(sb.ToString()) }, references: references, options: compilationOptions); // 执行编译并生成内存中的程序集 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()}"); } throw new InvalidOperationException("动态代码编译失败"); } // 加载编译好的程序集 ms.Seek(0, SeekOrigin.Begin); var assembly = Assembly.Load(ms.ToArray()); // 实例化动态类并调用方法 var dynamicType = assembly.GetType(className); var instance = Activator.CreateInstance(dynamicType); var targetMethod = dynamicType.GetMethod("GetDynamicResult"); var result = targetMethod.Invoke(instance, null); Console.WriteLine(result);
关键说明
- Roslyn是.NET生态的官方编译器,完全支持.NET Standard/.NET Core/.NET 5+等现代.NET环境,跨平台能力拉满。
- 不需要再依赖老旧的CodeDom API,彻底解决平台不支持的问题。
- 编译时需要确保引用了所有动态代码依赖的程序集,你可以根据自己的动态代码需求调整
references列表。
内容的提问来源于stack exchange,提问作者Andrei Barbolin
相关产品推荐
相关产品推荐

