C# 静态代码织入AOP组件之肉夹馍

发布时间:2024年01月14日

写在前面

关于肉夹馍组件的官方介绍说明:

Rougamo是一个静态代码织入的AOP组件,同为AOP组件较为常用的有Castle、Autofac、AspectCore等,与这些组件不同的是,这些组件基本都是通过动态代理+IoC的方式实现AOP,是运行时完成的,而Rougamo是编译时直接修改目标方法织入IL代码的。如果你还知道一个AOP组件"PostSharp",那么Rougamo就是类似Postsharp的一个组件,Postsharp是一个成熟稳定的静态代码织入组件,但PostSharp是一款商业软件,一些常用的功能在免费版本中并不提供。

老规矩从NuGet 安装组件?Rougamo.Fody

代码实现

以下是最基础的一个应用肉夹馍AOP组件的实现代码

?注入代码主体[LoggingAttribute]:

    public class LoggingAttribute : MoAttribute
    {
        private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();

        public override void OnEntry(MethodContext context)
        {
            // 从context对象中能取到包括入参、类实例、方法描述等信息
            Logger.Info("方法执行前");
        }

        public override void OnException(MethodContext context)
        {
            Logger.Error("方法执行异常", context.Exception);            
        }

        public override void OnSuccess(MethodContext context)
        {
            Logger.Info("方法执行成功后");
        }

        public override void OnExit(MethodContext context)
        {
            Logger.Info("方法退出时,不论方法执行成功还是异常,都会执行");
        }
    }

    // 3.应用Attribute
    public class Service
    {
        [Logging]
        public static int Sync(Model model)
        {
            return model.Id;
        }

        [Logging]
        public async Task<Data> Async(int id)
        {
            return await Task.Run(() =>
            {
                var data = new Data();
                data.Id = id;
                return data;
            });
        }
    }

    public class Model
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    public class Data
    {
        public int Id { get; set; }
    }

调用代码:

    public static void Main(string[] args)
    {
        Console.WriteLine("Start...");

        var config = new NLog.Config.LoggingConfiguration();

        // Targets where to log to: File and Console
        var logfile = new NLog.Targets.FileTarget("logfile") { FileName = "file.txt" };
        var logconsole = new NLog.Targets.ConsoleTarget("logconsole");

        // Rules for mapping loggers to targets            
        config.AddRule(LogLevel.Info, LogLevel.Fatal, logconsole);
        config.AddRule(LogLevel.Debug, LogLevel.Fatal, logfile);

        // Apply config           
        LogManager.Configuration = config;

        var service = new Service();
        var data = service.Async(1);
        var id = Service.Sync(new Model() { Id = 1, Name = "DemoModel" });
        Console.WriteLine($"Data Id: {data.Id}, Model Id: {id}");

        Console.ReadLine();
    }

调用示例

?

文章来源:https://blog.csdn.net/rjcql/article/details/135590283
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。