增量源生成器引用DotLiquid库时运行时加载失败的解决方法
问题解决方法
1. 修正项目打包配置冲突
你的csproj中同时设置了<IsPackable>false</IsPackable>和<GeneratePackageOnBuild>true</GeneratePackageOnBuild>,二者存在冲突会导致打包行为异常,先将<IsPackable>改为true:
<IsPackable>true</IsPackable>
2. 将DotLiquid依赖嵌入生成器程序集(推荐方案)
源生成器运行在Roslyn进程中,直接打包依赖到analyzers目录可能存在加载路径问题,更可靠的方式是把DotLiquid的DLL嵌入到生成器程序集内,具体操作如下:
修改csproj配置
- 移除原配置中
<None Include="$(PkgDotLiquid)\lib\netstandard2.0\*.dll"...>这一行 - 添加嵌入资源配置:
<ItemGroup> <EmbeddedResource Include="$(PkgDotLiquid)\lib\netstandard2.0\DotLiquid.dll"> <LogicalName>DotLiquid.dll</LogicalName> </EmbeddedResource> </ItemGroup>
添加程序集解析逻辑
在生成器项目中添加静态解析类,处理嵌入资源的加载:
namespace SourceGenerators1; public static class AssemblyResolver { static AssemblyResolver() { AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => { var assemblyName = new AssemblyName(args.Name).Name; var resourceName = $"{typeof(AssemblyResolver).Namespace}.{assemblyName}.dll"; using var stream = typeof(AssemblyResolver).Assembly.GetManifestResourceStream(resourceName); if (stream == null) return null; var assemblyBytes = new byte[stream.Length]; stream.Read(assemblyBytes, 0, assemblyBytes.Length); return Assembly.Load(assemblyBytes); }; } public static void Initialize() { } }
然后在生成器的Initialize方法开头调用初始化:
public void Initialize(IncrementalGeneratorInitializationContext context) { AssemblyResolver.Initialize(); var template = Template.Parse(""); }
3. 备选方案:确保依赖被正确复制并打包
如果不想嵌入资源,可通过以下步骤确保依赖被正确加载:
- 在PropertyGroup中添加配置,确保依赖被复制到输出目录:
<PropertyGroup> <!-- 其他已有配置 --> <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> </PropertyGroup>
- 修改打包的None项,引用输出目录的DotLiquid.dll:
<None Include="$(OutputPath)\DotLiquid.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
4. 验证打包结果
构建项目后,用解压工具打开生成的NuGet包,确认analyzers/dotnet/cs目录下:
- 嵌入方案:仅存在你的生成器DLL
- 复制方案:同时存在生成器DLL和DotLiquid.dll
在测试项目中安装该NuGet包,重新构建即可解决加载问题。
内容的提问来源于stack exchange,提问作者Kosmonik
相关产品推荐
相关产品推荐

