嵌套.NET代码生成器依赖GeneratorLib加载失败问题求助
代码生成器嵌套依赖加载失败:原因分析与修复方案
原因分析
代码生成器运行在Roslyn的专用分析进程中,其程序集加载逻辑和常规.NET应用完全不同:
- 当
ActualProgram引用Generator2时,Roslyn只会自动加载直接标记为分析器的程序集(Generator2),而Generator2依赖的Generator1、Generator1依赖的GeneratorLib不会被自动纳入Roslyn的加载路径——哪怕这些文件存在于项目bin目录中。 AutoGenerateBindingRedirects仅对常规应用程序生效,代码生成器的加载上下文不遵循这套绑定重定向规则,所以该配置无法解决问题。- .NET 8项目引用netstandard2.0代码生成器时,跨框架的依赖解析存在额外的上下文差异,进一步加剧了程序集找不到的问题。
修复方法
1. 配置项目引用为Analyzer组件
修改所有生成器项目的引用配置,让依赖链上的所有程序集都被标记为Analyzer组件,确保Roslyn能识别并加载它们:
- 在
Generator1.csproj中修改对GeneratorLib的引用:<ProjectReference Include="..\GeneratorLib\GeneratorLib.csproj"> <PrivateAssets>none</PrivateAssets> <OutputItemType>Analyzer</OutputItemType> <ReferenceOutputAssembly>true</ReferenceOutputAssembly> </ProjectReference> - 在
Generator2.csproj中修改对Generator1的引用:<ProjectReference Include="..\Generator1\Generator1.csproj"> <OutputItemType>Analyzer</OutputItemType> <ReferenceOutputAssembly>true</ReferenceOutputAssembly> </ProjectReference> - 在
ActualProgram.csproj中保持对Generator2的引用配置为Analyzer类型。
2. 添加程序集解析钩子
如果上述方法无法生效,可以在Generator1的构造函数中添加程序集解析事件,手动定位并加载GeneratorLib:
using System.IO; using System.Reflection; public Generator1() { Debugger.Launch(); AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => { var assemblyName = new AssemblyName(args.Name); var targetPath = Path.Combine( Path.GetDirectoryName(typeof(Generator1).Assembly.Location), $"{assemblyName.Name}.dll" ); return File.Exists(targetPath) ? Assembly.LoadFrom(targetPath) : null; }; }
同时在Generator1.csproj中添加PostBuild事件,确保GeneratorLib.dll被复制到Generator1的输出目录:
<Target Name="CopyGeneratorLibDependency" AfterTargets="Build"> <Copy SourceFiles="..\GeneratorLib\bin\$(Configuration)\netstandard2.0\GeneratorLib.dll" DestinationFolder="$(OutputPath)" /> </Target>
3. 统一目标框架版本
将GeneratorLib、Generator1、Generator2的目标框架升级为.NET Standard 2.1或直接使用.NET 8,减少跨框架依赖解析的兼容性问题。Roslyn对较新的目标框架程序集的加载逻辑更完善,能避免很多隐性的加载失败问题。
内容的提问来源于stack exchange,提问作者infinitezero
相关产品推荐
相关产品推荐

