• C# 12 拦截器 Interceptors


    拦截器Interceptors是一种可以在编译时以声明方式替换原有应用的方法。

    这种替换是通过让Interceptors声明它拦截的调用的源位置来实现的。

    您可以使用拦截器作为源生成器的一部分进行修改,而不是向现有源编译添加代码。

     

    演示

    使用 .NET 8 创建一个控制台应用程序。并在PropertyGroup中添加以下配置.。需要将其中WebApplication6替换为自己的命名空间。

    $(InterceptorsPreviewNamespaces);WebApplication6

    然后在单独的文件中创建InterceptsLocationAttribute。其命名空间必须是System.Runtime.CompilerServices,而不是应用程序的命名空间。

    复制代码
    namespace System.Runtime.CompilerServices
    {
        [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
        public sealed class InterceptsLocationAttribute(string filePath, int line, int character) : Attribute
        {
        }
    }
    复制代码

    该属性包含三个参数。

    • filePath是您要拦截的文件的路径。
    • line是您要拦截的代码行。
    • character是您要拦截的代码字符位置。

    接着来创建一个具有三种方法的类,模拟新增/查询用户作为示例:

    复制代码
    public class GetUserService
    {
        // This method will not be intercepted;
        public void GetUserName()
        {
            Console.WriteLine("GetUserName");
        }
    
        // This method will be intercepted;
        public void AddUser()
        {
            Console.WriteLine("AddUser");
        }
    
        // This method will not be intercepted;
        public void DeleteUser()
        {
            Console.WriteLine("DeleteUser");
        }
    }
    复制代码

    在 Program.cs 文件中,我创建了此类的一个实例,并创建了对这三个方法中每一个的调用。输出如下所示:

    var userService = new GetUserService();
    
    userService.GetUserName();
    userService.AddUser();
    userService.DeleteUser();

    现在让我们创建拦截类。该类必须遵循以下规则:

    • 一定是一个static类。
    • 必须是我们要拦截的类的扩展方法。
    • 必须具有该InterceptsLocation属性,其中包含我们要拦截的文件路径的值以及行号和字符号。

     

    复制代码
    using System.Runtime.CompilerServices;
    
    namespace WebApplication6
    {
        public static class InterceptUserService
        {
            [InterceptsLocation(
        filePath: @"D:\demo\test\ConsoleApp1\WebApplication6\Program.cs",
        line: 14,
        character: 25)]
            public static void InterceptMethodAddUser(this GetUserService example)
            {
                Console.WriteLine("Interceptor is here!");
            }
        }
    }
    复制代码

    在此示例中,将拦截AddUser方法,并且将执行InterceptMethodAddUser方法,而不是执行方法AddUser。

    filePath可以按以下方式获取

     

    行号和字符号可以按以下方式获取

     

    现在运行代码,方法AddUser将被拦截,并且不会被执行,而是实际执行拦截器方法,以下是输出:

     


  • 相关阅读:
    网络安全(黑客)自学笔记1.0
    RabbitMQ消息的链路跟踪
    基于逻辑规则的图谱推理
    构建客户门户的痛点及低代码工具解决方案
    再学DataX
    思科模拟器的远程连接交换机的实现
    基于JAVA线上动漫周边商城计算机毕业设计源码+数据库+lw文档+系统+部署
    5个超实用的Python代码片段
    下班时间做抖音小店,连直播都不会的我,7天销售额流水50多万
    java计算机毕业设计房屋租赁网站源码+mysql数据库+系统+lw文档+部署
  • 原文地址:https://www.cnblogs.com/chenyishi/p/18082725