學習Source Generators之打包成Nuget使用

饭勺oO發表於2024-04-11

前面我們簡單的實現了一個從swagger生成實體類的Generator,在實際使用中,透過nuget包引用使用會更方便,那麼本篇文章將介紹如何將Generator打包成Nuget來使用。

打包Nuget

這裡我們將GenerateClassFromSwagger.Analysis打包成Nuget進行使用。
首先需要修改專案檔案。

修改專案檔案

在PropertyGroup新增true表示在編譯時生成nuget包以及false表示不要將生成器作為庫依賴項包括在內。
以及新增ItemGroup 包含將生成器打包到nuget包的分析器目錄中
如果沒有第三方依賴的時候,僅這些配置已經足夠了。如果需要依賴第三方元件。
這裡我們依賴了Newtonsoft.Json的包,則需要新增 來指定和Generator的依賴關係。
完整修改後的專案配置如下:

<Project Sdk="Microsoft.NET.Sdk">

	<PropertyGroup>
		<TargetFramework>netstandard2.0</TargetFramework>
		<LangVersion>latest</LangVersion>
		<Version>1.0.2</Version>
		<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
		<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
		<GetTargetPathDependsOn>$(GetTargetPathDependsOn);GetDependencyTargetPaths</GetTargetPathDependsOn>
		<GeneratePackageOnBuild>true</GeneratePackageOnBuild><!-- Generates a package at build -->
		<IncludeBuildOutput>false</IncludeBuildOutput><!-- Do not include the generator as a lib dependency -->
	</PropertyGroup>

	<ItemGroup>
		<PackageReference Include="Newtonsoft.Json" Version="13.0.3" PrivateAssets="all" GeneratePathProperty="true" />
		<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.2.0" PrivateAssets="all" />
		<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" PrivateAssets="all" />
	</ItemGroup>

	<Target Name="GetDependencyTargetPaths" AfterTargets="ResolvePackageDependenciesForBuild">
		<ItemGroup>
			<TargetPathWithTargetPlatformMoniker Include="@(ResolvedCompileFileDefinitions)" IncludeRuntimeDependency="false" />
		</ItemGroup>
	</Target>

	<ItemGroup>
		<!-- Package the generator in the analyzer directory of the nuget package -->
		<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />

		<!-- Package the Newtonsoft.Json dependency alongside the generator assembly -->
		<None Include="$(PkgNewtonsoft_Json)\lib\netstandard2.0\*.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
	</ItemGroup>
</Project>

編譯專案

修改專案檔案後,編譯專案,可以在Debug目錄下看到nupkg檔案。
image.png
將檔案上傳到nuget.org,等待上架成功後可以在NUGET包管理器搜尋並安裝。

安裝Nuget

首先建立一個GenerateClassFromSwaggerNuget的控制檯專案,然後新增Nuget依賴。搜尋GenerateClassFromSwagger.Analysis即可找到。
image.png
將我們的swagger.json複製一份過來並設定成AdditionalFiles。
image.png
修改包屬性的OutputItemType和ReferenceOutputAssembly
完整配置如下:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <AdditionalFiles Include="Files\swagger.json" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="GenerateClassFromSwagger.Analysis" Version="1.0.2" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
  </ItemGroup>

</Project>

編譯控制檯專案

接下來編譯GenerateClassFromSwaggerNuget專案,編譯完成後。可以在分析器看到我們生成的檔案
image.png
image.png
跟我們直接引用專案依賴的效果一致。

輸出檔案

同樣,如果我們需要輸出檔案,在專案檔案中新增EmitCompilerGeneratedFiles標籤。

<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>

然後再次編譯。可以在obj目錄中找到生成的檔案列表。
image.png
如果需要輸出到指定目錄,則跟上篇文章的方式一致,這裡就不贅述了。

結語

本片文章介紹了將Generator打包成Nuget進行使用,可以更方便的在不同專案中使用。

本文程式碼倉庫地址https://github.com/fanslead/Learn-SourceGenerator

相關文章