新建 C# 源生成器项目

Microsoft Learn源生成器文档现在只给了一个链接,指向的文档居然没讲最关键的部分——如何新建一个源生成器项目!

遂写下记录,防止我自己忘记如何创建源生成器。


新建项目

  1. 新建一个 C# 类库项目,目标框架选择 .NET Standard 2.0,这是硬性要求。
  2. 引入两个 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>

注意,这两个包的版本是要根据使用源生成器的项目的目标框架决定的,如果版本不匹配,源生成器将无法运行,建议根据需要使用的特性选择最低的可用版本以实现最佳兼容性。

  1. 现在需要修改项目文件,添加
<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>
  1. 新建源生成器类

在项目中新建一个类,名字随意,继承 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>

调试源生成器

为了能够调试源生成器,还需要修改项目属性。

  1. 右键项目,点击菜单中的“属性”选项
  2. 在界面左边的导航栏点击“调试”,再点击“打开调试配置启动 UI
    image
  3. 删除默认配置,添加新配置。
  4. 在 Target Project 中的下拉框选中引用了该源生成器的项目(如果没有的话这里会没有可选项)
    image
  5. 修改启动项目为源生成器所在的项目。

例子

最终的项目文件类似:

<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


参考

  1. .NET 编译器平台 SDK
  2. Package a generator as a NuGet package
  3. How to debug source generator
  4. Use functionality from NuGet packages
posted @ 2026-03-11 01:43  Nebulae_Flood  阅读(14)  评论(0)    收藏  举报