新建 C# 源生成器项目
Microsoft Learn 的源生成器文档现在只给了一个链接,指向的文档居然没讲最关键的部分——如何新建一个源生成器项目!
遂写下记录,防止我自己忘记如何创建源生成器。
新建项目
- 新建一个 C# 类库项目,目标框架选择 .NET Standard 2.0,这是硬性要求。
- 引入两个 Nuget 包,分别是
别忘记给项目文件的引用加上 PrivateAssets="all",或者你可以直接复制以下内容到项目文件:
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" PrivateAssets="all"/>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.3.0" PrivateAssets="all"/>
</ItemGroup>
注意,这两个包的版本是要根据使用源生成器的项目的目标框架决定的,如果版本不匹配,源生成器将无法运行,建议根据需要使用的特性选择最低的可用版本以实现最佳兼容性。
- 现在需要修改项目文件,添加
<PropertyGroup>
<CompilerGeneratedFilesOutputPath>Generated</CompilerGeneratedFilesOutputPath>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
<!-- 防止将源生成器被作为普通库引用 -->
<IncludeBuildOutput>false</IncludeBuildOutput>
<IsRoslynComponent>true</IsRoslynComponent>
</PropertyGroup>
<!-- 隐藏编译后的 bin 文件夹 -->
<Target Name="AddAnalyzerToPackage" AfterTargets="Build">
<ItemGroup>
<!-- 使打包成 Nuget 包的源生成器能被自动识别 -->
<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
</ItemGroup>
</Target>
- 新建源生成器类
在项目中新建一个类,名字随意,继承 IIncrementalGenerators,并为该类添加一个 Attribute [Generator],完成后代码类似
[Generator]
public sealed class MySourceGenerator : IIncrementalGenerator
{
public void Initialize(IncrementalGeneratorInitializationContext context)
{
throw new NotImplementedException();
}
}
引用源生成器
要使用源生成器,还要修改引用源生成器的项目的项目文件,给 PackageReference 加上 OutputItemType="Analyzer" ReferenceOutputAssembly="false",结果类似
<ItemGroup>
<ProjectReference Include="MySourceGenerator.csproj"
OutputItemType="Analyzer"
ReferenceOutputAssembly="false"/>
</ItemGroup>
调试源生成器
为了能够调试源生成器,还需要修改项目属性。
- 右键项目,点击菜单中的“属性”选项
- 在界面左边的导航栏点击“调试”,再点击“打开调试配置启动 UI”

- 删除默认配置,添加新配置。
- 在 Target Project 中的下拉框选中引用了该源生成器的项目(如果没有的话这里会没有可选项)

- 修改启动项目为源生成器所在的项目。
例子
最终的项目文件类似:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<CompilerGeneratedFilesOutputPath>Generated</CompilerGeneratedFilesOutputPath>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
<!-- 防止将源生成器被作为普通库引用 -->
<IncludeBuildOutput>false</IncludeBuildOutput>
<IsRoslynComponent>true</IsRoslynComponent>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" PrivateAssets="all"/>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.3.0" PrivateAssets="all"/>
</ItemGroup>
<!-- 隐藏编译后的 bin 文件夹 -->
<Target Name="AddAnalyzerToPackage" AfterTargets="Build">
<ItemGroup>
<!-- 使打包成 Nuget 包的源生成器能被自动识别 -->
<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" />
</ItemGroup>
</Target>
</Project>
其它
如果想要一个 Nuget 包仅在源生成器内部使用,参考 Use functionality from NuGet packages 不想读英文的话可以问 AI

浙公网安备 33010602011771号