前言
写分析器(源生成器)时经常需要引用别的包,但直接引用是无法运行的。
下面我们分不同情况来讨论在分析器项目如何对依赖进行引用。
下图中“包引用”指PackageReference
,“项目引用”指ProjectReference
。
其中项目引用是通过dll文件传递的,包引用是通过nupkg文件传递的,
最大的区别是项目引用默认不可以传递,而包引用默认可以传递。
注:首先需要确保引用的包支持.NET Standard 2.0。
直接项目引用
在很多时候只需要写一个特化的源生成器供项目使用时,会使用直接项目引用的方式。
此时我们将需要引用的dll路径告诉分析器即可。
在csproj项目文件中用以下语句[1]即可实现这个功能(以System.Text.Json
为例):
<ItemGroup> <PackageReference Include="System.Text.Json" Version="8.0.1" GeneratePathProperty="true" PrivateAssets="all" ReferenceOutputAssembly="false" /> </ItemGroup> <PropertyGroup> <GetTargetPathDependsOn>$(GetTargetPathDependsOn);GetDependencyTargetPaths</GetTargetPathDependsOn> </PropertyGroup> <Target Name="GetDependencyTargetPaths"> <ItemGroup> <TargetPathWithTargetPlatformMoniker Include="$(PkgSystem_Text_Json)\lib\netstandard2.0\*.dll" IncludeRuntimeDependency="false" /> </ItemGroup> </Target>
第一部分ItemGroup
是引用包项目。其中:
-
PrivateAssets
指定了这个依赖不会传递给用户项目,如果需要传递的话,则无需指定这句; -
ReferenceOutputAssembly
是是否引用这个包,例如“NuGet包传递”模式中,也许只有分析器项目才需要使用这个包,NuGet包主项目并不需要它,即可指定这个属性; -
GeneratePathProperty
是生成PkgSystem_Text_Json
属性,我们可以用$(PkgSystem_Text_Json)
的方法去获取这个包的dll所在路径,规律是Pkg+包名,其中包名中的点替换为下划线。
第二部分PropertyGroup
是指定需要GetDependencyTargetPaths
这个Target
。
第三部分Target
指定了GetDependencyTargetPaths
具体如何实现,即将告诉编译器指定dll的路径。
NuGet打包
但由于获取的dll路径是绝对路径,在生成项目时就已经决定了。
NuGet包绝大多数情况都和生成包的设备环境不同,此时上一个方法就失效了。
此时我们可以将需要的dll项目打包进nupkg中:
这个功能(以System.Text.Json
为例):
<ItemGroup> <PackageReference Include="System.Text.Json" Version="8.0.1" GeneratePathProperty="true" PrivateAssets="all" ReferenceOutputAssembly="false" /> <None Include="$(PkgSystem_Text_Json)\lib\netstandard2.0\System.Text.Json.dll" Pack="true" PackagePath="analyzers\dotnet\cs\System.Text.Json.dll" Visible="false" CopyToOutputDirectory="PreserveNewest"/> </ItemGroup>
一个解决方案有很多项目,那上面的问题应该写在哪呢?有一个很容易的判断标准:
写在用户项目引用的对象上。
举例来说“NuGet包传递”中,NuGet包项目引用了分析器项目的nupkg后传递给了用户项目,本质上引用的是分析器项目(因为用户项目也可以直接引用分析器项目NuGet包),所以我们应该写在分析器的csproj中。
“单NuGet包项目”中,NuGet包主项目会将分析器项目的dll包含进输出的nupkg中,所以我们应该写在NuGet包主项目的csproj中。
但这种方法会导致nupkg包变大,如果大家有更好的方法可以教我噢【
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 易语言 —— 开山篇