我正在开发一个源生成器,它生成我希望其他开发人员使用的实用程序类。我的发电机工作正常。我的问题是将文件发送到磁盘。我可以通过
将文件发送到磁盘 <PropertyGroup>
<!--Persist the source generator (and other) files to disk-->
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<!--👇 The "base" path for the source generators-->
<GeneratedFolder>Generated</GeneratedFolder>
<!--👇 Write the output for each target framework to a different sub-folder-->
<CompilerGeneratedFilesOutputPath>$(GeneratedFolder)\$(TargetFramework)</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
以上效果很好。但是,您无法再次运行生成器,因为类型已经定义。
解决此问题的一个简单方法是从编译中删除生成的类型。这是不希望的,因为开发人员会失去智能。
下一个选项是在预构建期间删除生成的目录。
<Target Name="CleanSourceGeneratedFiles" BeforeTargets="BeforeBuild" DependsOnTargets="$(BeforeBuildDependsOn)">
<RemoveDir Directories="Generated" />
</Target>
这确实有效,但现在所有其他构建都因丢失文件而失败。
由于符号已被加载,因此您无法删除生成的文件并在源生成器期间重新生成它们。
如何创建一个源生成器,将文件发送到磁盘并为开发人员提供智能?
您可以告诉编译器忽略它,而不是删除包含生成文件的文件夹的目标:
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>Generated</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
...
<ItemGroup>
<ProjectReference Include="..\PathTo\MyGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
<Compile Remove="$(CompilerGeneratedFilesOutputPath)/**/*.cs" />
</ItemGroup>
这种方法还允许将生成的代码保存在源代码管理中。另外,我很确定 IntelliSense 不以任何方式依赖这些文件;它只查看内存中生成的代码。