通过ISourceGenerator可以实现代码生成,这个例子网上好多,就不再重复说了,但是有几个关键点不注意的话,生成不了代码
项目结构如下
1、dll代码
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Text; using System.Text; namespace SourceGeneratorSamples { [Generator] public class HelloWorldGenerator : ISourceGenerator { public void Execute(GeneratorExecutionContext context) { // begin creating the source we'll inject into the users compilation var sourceBuilder = new StringBuilder(@" using System; namespace HelloWorldGenerated { public static class HelloWorld { public static void SayHello() { Console.WriteLine(""Hello from generated code!""); Console.WriteLine(""The following syntax trees existed in the compilation that created this program:""); "); // using the context, get a list of syntax trees in the users compilation var syntaxTrees = context.Compilation.SyntaxTrees; // add the filepath of each tree to the class we're building foreach (SyntaxTree tree in syntaxTrees) { sourceBuilder.AppendLine($@"Console.WriteLine(@"" - {tree.FilePath}"");"); } // finish creating the source to inject sourceBuilder.Append(@" } } }"); // inject the created source into the users compilation context.AddSource("helloWorldGenerator", SourceText.From(sourceBuilder.ToString(), Encoding.UTF8)); } public void Initialize(GeneratorInitializationContext context) { // No initialization required for this one } } }
2、调用代码
using Nest; using System; using SourceGeneratorSamples; namespace ConsoleApp2 { class Program { static void Main(string[] args) { SomeMethodIHave(); } static void SomeMethodIHave() { HelloWorldGenerated.HelloWorld.SayHello(); // calls Console.WriteLine("Hello World!") and then prints out syntax trees } } }
3、需要注意两点
调用者proj文件里要这样写
<ItemGroup> <ProjectReference Include="..ClassLibrary2ClassLibrary2.csproj"> <Private>true</Private> </ProjectReference> </ItemGroup> <ItemGroup> <Analyzer Include="..ClassLibrary2inDebug etstandard2.0ClassLibrary2.dll"/> </ItemGroup>
或者这样写
<ItemGroup> <ProjectReference Include="..ClassLibrary2ClassLibrary2.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="true"/> </ItemGroup>