title: 分析器/源生成器添加項(xiàng)目依賴的方式
date: 2024-01-20
categories: 編程
tags:
- C#
- .NET
- Roslyn
前言
寫分析器(源生成器)時(shí)經(jīng)常需要引用別的包,但直接引用是無法運(yùn)行的。
下面我們分不同情況來討論在分析器項(xiàng)目如何對(duì)依賴進(jìn)行引用。
下圖中“包引用”指PackageReference
,“項(xiàng)目引用”指ProjectReference
。
其中項(xiàng)目引用是通過dll文件傳遞的,包引用是通過nupkg文件傳遞的,
最大的區(qū)別是項(xiàng)目引用默認(rèn)不可以傳遞,而包引用默認(rèn)可以傳遞。
注:首先需要確保引用的包支持.NET Standard 2.0。
直接項(xiàng)目引用
在很多時(shí)候只需要寫一個(gè)特化的源生成器供項(xiàng)目使用時(shí),會(huì)使用直接項(xiàng)目引用的方式。
此時(shí)我們將需要引用的dll路徑告訴分析器即可。
在csproj項(xiàng)目文件中用以下語句[1]即可實(shí)現(xiàn)這個(gè)功能(以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
是引用包項(xiàng)目。其中:
-
PrivateAssets
指定了這個(gè)依賴不會(huì)傳遞給用戶項(xiàng)目,如果需要傳遞的話,則無需指定這句; -
ReferenceOutputAssembly
是是否引用這個(gè)包,例如“NuGet包傳遞”模式中,也許只有分析器項(xiàng)目才需要使用這個(gè)包,NuGet包主項(xiàng)目并不需要它,即可指定這個(gè)屬性; -
GeneratePathProperty
是生成PkgSystem_Text_Json
屬性,我們可以用$(PkgSystem_Text_Json)
的方法去獲取這個(gè)包的dll所在路徑,規(guī)律是Pkg+包名,其中包名中的點(diǎn)替換為下劃線。
第二部分PropertyGroup
是指定需要GetDependencyTargetPaths
這個(gè)Target
。
第三部分Target
指定了GetDependencyTargetPaths
具體如何實(shí)現(xiàn),即將告訴編譯器指定dll的路徑。
NuGet打包
但由于獲取的dll路徑是絕對(duì)路徑,在生成項(xiàng)目時(shí)就已經(jīng)決定了。
NuGet包絕大多數(shù)情況都和生成包的設(shè)備環(huán)境不同,此時(shí)上一個(gè)方法就失效了。
此時(shí)我們可以將需要的dll項(xiàng)目打包進(jìn)nupkg中:
這個(gè)功能(以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>
一個(gè)解決方案有很多項(xiàng)目,那上面的問題應(yīng)該寫在哪呢?有一個(gè)很容易的判斷標(biāo)準(zhǔn):
寫在用戶項(xiàng)目引用的對(duì)象上。
舉例來說“NuGet包傳遞”中,NuGet包項(xiàng)目引用了分析器項(xiàng)目的nupkg后傳遞給了用戶項(xiàng)目,本質(zhì)上引用的是分析器項(xiàng)目(因?yàn)橛脩繇?xiàng)目也可以直接引用分析器項(xiàng)目NuGet包),所以我們應(yīng)該寫在分析器的csproj中。
“單NuGet包項(xiàng)目”中,NuGet包主項(xiàng)目會(huì)將分析器項(xiàng)目的dll包含進(jìn)輸出的nupkg中,所以我們應(yīng)該寫在NuGet包主項(xiàng)目的csproj中。
但這種方法會(huì)導(dǎo)致nupkg包變大,如果大家有更好的方法可以教我噢【文章來源:http://www.zghlxwxcb.cn/news/detail-807277.html
-
GitHub Disscussion ??文章來源地址http://www.zghlxwxcb.cn/news/detail-807277.html
到了這里,關(guān)于分析器/源生成器添加項(xiàng)目依賴的方式的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!