最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

【聚看点】Source Generator初探

来源:博客园

Source Generator

什么是Source Generator

.NET 5引入的系特性,可在应用编译期间根据当前编译信息动态生成代码,也可以直接引用动态生成的代码。

优势

加快运行速度

原有的程序机制是初次运行时通过反射进行依赖注入,这时会导致第一次运行加载大量数据,运行会慢,再一个不利于AOT编译。

而Source Generator是在编译时完成依赖注入,把之前运行所作的大部分工作都完成,这样即可利于AOT编译,又可以保证运行时的速度。


(资料图)

增加了代码的灵活性

将运行时加载变为了编译时加载,可以让程序在编译时动态加载程序员想要的代码,这些代码可以来源于Xml,JSON等文件,依次类推,我们可以通过维护Xml或者JSON来动态编译实现无代码平台。

解决AOT编译

AOT也是一个新特性,但使用反射的程序无法使用该特性,使用Source Generator可避免AOT特性无法使用的情况。

第一个Source Generator例子

  • 创建一个控制台程序

    1. 选择控制台应用,下一步

    2. 创建项目名称,下一步

    3. 框架选择默认(目前默认的为Net 6.0),并勾选不适用顶级语句,创建项目

    4. 修改Program.cs代码,修改部分如下:

      namespace SourceGeneratorDemo{    // internal 改为 partial,否则可见级别太低,使用public的话Program可见级别太高    partial class Program    {        static void Main(string[] args)        {            Console.WriteLine("Hello, World!");            // 添加该行            HelloCode("Hello, Code");        }        // 添加该行 动态编译并调用HelloCode        static partial void HelloCode(string name);    }}
    5. 此时,直接编译并运行可通过,HelloCode方法未找到会自动跳过

  • 创建netstandard2.0的类库项目

    1. 选择类库项目,下一步

    2. 添加项目名称,下一步

    3. 选择框架(netstandard2.0),创建

    4. 添加Microsoft.CodeAnalysis.Analyzers 和 Microsoft.CodeAnalysis.CSharp依赖,依赖项信息可通过点击项目进行查看

                all      runtime; build; native; contentfiles; analyzers; buildtransitive          
    5. 将Class1.cs改名为SourceGeneratorMethod.cs,并添加代码

      [Generator]public class HelloSourceGenerator : ISourceGenerator{    public void Execute(GeneratorExecutionContext context)    {        // Find the main method        var mainMethod = context.Compilation.GetEntryPoint(context.CancellationToken);        // Build up the source code        string source = $@"// using System;namespace {mainMethod.ContainingNamespace.ToDisplayString()}{{public static partial class {mainMethod.ContainingType.Name}{{    static partial void HelloCode(string name) =>        Console.WriteLine($""Generator says: Hi from "{{name}}""");}}}}";        var typeName = mainMethod.ContainingType.Name;        // Add the source code to the compilation        context.AddSource($"{typeName}.g.cs", source);    }    public void Initialize(GeneratorInitializationContext context)    {        // No initialization required for this one    }}
    6. 编译SourceGenerator项目

  • 在控制台中添加对类库的依赖

    1. SourceGeneratorDemo项目中选择依赖项,点击右键添加项目引用,引用类库项目

    2. 双击SourceGeneratorDemo项目,添加OutputItemTypeReferenceOutputAssembly属性

            
    3. 生成SourceGeneratorDemo并运行

    4. 结果,并没有输出Hello, Code

  • 问题解决

    1. 重新打开项目

    2. 将Microsoft.CodeAnalysis.Analyzers 和 Microsoft.CodeAnalysis.CSharp引用修改为如下引用:

                    all      runtime; build; native; contentfiles; analyzers; buildtransitive      
    3. 清理SourceGenerator和SourceGeneratorDemo项目

    4. 重新运行,出现了Hello,Code

  • 原因判断:

    • 经测试,Microsoft.CodeAnalysis.Analyzers可不使用,只需要引用Microsoft.CodeAnalysis.CSharp即可

    • Microsoft.CodeAnalysis.CSharp的4.5.0版本和4.6.0-1.final执行无法达到效果,还未找到原因

关键词: