如何从System.CodeDom.Compiler迁移至Roslyn API?代码适配求助
将旧CSharpCodeProvider代码迁移到Roslyn API
核心配置映射
原代码中CompilerParameters和CSharpCodeProvider的配置可直接对应到Roslyn的API,具体映射关系如下:
/t:library编译选项 →OutputKind.DynamicallyLinkedLibrary- C# 4.0版本指定 →
LanguageVersion.CSharp4 - 引用程序集集合 →
MetadataReference列表 - 内存生成程序集 → 通过
MemoryStream加载编译字节码实现
完整迁移代码
替换原有的编译逻辑为以下Roslyn实现:
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using System.IO; using System.Reflection; using System.Collections.Generic; // 保留原有源代码拼接逻辑 sourceCode = $@" using System; {string.Format(Constants.Assembly.UsingDirective, Constants.Assembly.DapperNamespace)} namespace {Constants.Assembly.DynamicTypeNamespace} {{ {sourceCode} }}"; // 1. 将源代码解析为Roslyn语法树 SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(sourceCode); // 2. 创建编译选项,对应原CompilerParameters的配置 CSharpCompilationOptions compilationOptions = new CSharpCompilationOptions( outputKind: OutputKind.DynamicallyLinkedLibrary, // 等价于/t:library languageVersion: LanguageVersion.CSharp4 // 指定C#4编译版本 ); // 3. 构建引用程序集列表,对应原ReferencedAssemblies List<MetadataReference> references = new List<MetadataReference>(); foreach (string assemblyPath in baseAssemblyLocations) { references.Add(MetadataReference.CreateFromFile(assemblyPath)); } // 补充必要的系统依赖(若baseAssemblyLocations未包含) references.Add(MetadataReference.CreateFromFile(typeof(object).Assembly.Location)); references.Add(MetadataReference.CreateFromFile(typeof(Dapper.SqlMapper).Assembly.Location)); // 依赖Dapper时添加 // 4. 创建编译实例 CSharpCompilation compilation = CSharpCompilation.Create( assemblyName: Path.GetRandomFileName(), // 生成随机程序集名称 syntaxTrees: new[] { syntaxTree }, references: references, options: compilationOptions ); // 5. 执行编译并加载内存程序集 using (MemoryStream ms = new MemoryStream()) { EmitResult emitResult = compilation.Emit(ms); if (!emitResult.Success) { // 获取第一个编译错误并抛出 Diagnostic firstError = emitResult.Diagnostics.First(d => d.Severity == DiagnosticSeverity.Error); throw new Exception(firstError.GetMessage()); } // 重置流位置并加载程序集到内存 ms.Position = 0; Assembly = Assembly.Load(ms.ToArray()); }
关键说明
- Roslyn通过
SyntaxTree抽象源代码,替代原直接传入字符串的方式 CSharpCompilation是核心编译对象,整合了语法树、引用和编译选项三大要素- 内存生成程序集通过
MemoryStream中转,完全等价于原GenerateInMemory = true的行为 - 编译错误需从
EmitResult.Diagnostics中筛选错误级别的诊断信息
内容的提问来源于stack exchange,提问作者tRuEsAtM
相关产品推荐
相关产品推荐

