上一篇讲解了如何直接调用静态方法,而有时候我们会生成cs文件或其他格式的文件,进而使用Source Generator编译。本例中就对资源文件进行编译进行举例说明。
-
在Source Generator调用的基础上,创建一个新的类库项目(SourceGeneratorXmlMethod)
-
在项目上添加引用
<ItemGroup> <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.4.0" PrivateAssets="all" /> <PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> </ItemGroup>
-
新增cs文件(SourceGeneratorXmlGenerator),添加如下代码
using Microsoft.CodeAnalysis.Text; using Microsoft.CodeAnalysis; using System; using System.Text; using System.Linq; using System.Diagnostics; namespace SourceGeneratorXmlMethod { [Generator] public class SourceGeneratorXmlGenerator : ISourceGenerator { public void Initialize(GeneratorInitializationContext context) { } public void Execute(GeneratorExecutionContext context) { // 编译的时候弹出调试工具 Debugger.Launch(); // 获得查找格式为xml的文件(控制台命令的文件列表) var myFiles = context.AdditionalFiles.Where(at => at.Path.EndsWith(".xml")); foreach (var file in myFiles) { // 获得xml的文件信息 var content = file.GetText(context.CancellationToken); // 获得xml中的信息 String codes = content.ToString(); // 主要为演示,只是去掉了node标签 codes = codes.Replace("<root>", "").Replace("</root>", ""); // 动态编译 context.AddSource($"generated.cs", SourceText.From(codes, Encoding.UTF8)); } } } }
-
在SourceGeneratorConsole项目中添加file.xml文件,并添加如下信息
<root> namespace XmlMethodNamespace { public class XmlMethodClass { public static void StaticXmlMethod() { Console.WriteLine("Hellow Xml"); } } } </root>
root标签中为c#代码
-
双击SourceGeneratorConsole项目,修改file.xml的引用方式,改为
<ItemGroup> <AdditionalFiles Include="file.xml" CopyToOutputDirectory="PreserveNewest" /> </ItemGroup>
-
运行,会出现预期的结果:Hellow Xml
-
关于资源文件
- 资源文件的声明是在主项目中,而非实现ISourceGenerator接口的项目中。
- 如果启用了调试,请务必先将要使用的资源文件放入输出目录,否则context.AdditionalFiles中的文件一直是0。因为Debugger.Launch()是编译时调试,文件还未复制到输出目录中。
-
关于调试
-
可在ISourceGenerator接口实现代码中添加Debugger.Launch()方法,当编译或运行前会进入到弹出实时编译的选择
-
点击确定后就可对要生成的代码进行编译
-