zoukankan      html  css  js  c++  java
  • [AOP系列]Autofac+Castle实现AOP日志

    一、前言

    最近公司新项目,需要搭架构进行开发,其中需要对一些日志进行输出,经过一番查找,发现很多博文都是通过Spring.Net、Unity、PostSharp、Castle Windsor这些方式实现AOP的。但是这不是我想要的,因此一番查找后,使用Autofac、DynamicProxy该方式实现AOP。

    二、使用AOP的优势

    博主觉得它的优势主要表现在:

    • 将通用功能从业务逻辑中抽离出来,就可以省略大量重复代码,有利于代码的操作和维护。
    • 在软件设计时,抽出通用功能(切面),有利于软件设计的模块化,降低软件架构的复杂程度。也就是说通用的功能就是一个单独的模块,在项目的主业务里面是看不到这些通用功能的设计代码的。

    三、引用库

    • Autofac:4.6
    • Autofac.Extras.DynamicProxy:4.1.0
    • Castle.Core:3.2.2
    • log4net:2.08

    四、实现思路

    4.1 切面实现

    此处依赖自定义的日志组件,配置是否开启调试模式,如果启用调试模式,则会输出请求参数信息以及响应参数信息。
    代码如下:

    /// <summary>
    /// 日志 拦截器
    /// </summary>
    public class LoggingInterceptor:IInterceptor
    {
        /// <summary>
        /// 日志记录器
        /// </summary>
        private static readonly ILog Logger = Log.GetLog(typeof(LoggingInterceptor));
    
        public void Intercept(IInvocation invocation)
        {
            try
            {                
                if (Logger.IsDebugEnabled)
                {
                    Logger.Caption("日志拦截器-调试信息");
                    Logger.Class(invocation.TargetType.FullName);
                    Logger.Method(invocation.Method.Name);
                    Logger.Params("参数:{0}", invocation.Arguments.ToJson());                    
                }
                invocation.Proceed();
                if (Logger.IsDebugEnabled)
                {
                    if (invocation.ReturnValue != null && invocation.ReturnValue is IEnumerable)
                    {
                        dynamic collection = invocation.ReturnValue;
                        Logger.Content("结果:行数:{0}", collection.Count);
                    }
                    else
                    {
                        Logger.Content("结果:{0}", invocation.ReturnValue.ToJson());
                    }
                    Logger.Debug();
                }
            }
            catch (Exception e)
            {
                Logger.Caption("日志拦截器-异常");                
                Logger.Class(invocation.TargetType.FullName);
                Logger.Method(invocation.Method.Name);
                Logger.Params("参数:{0}", invocation.Arguments.ToJson());
                Logger.Exception(e);
                Logger.Error();
                throw;
            }
        }
    }
    

    4.3 切面注入

    博主对Autofac进行了封装,可能与你们的配置不一样,但是,Load(ContainerBuilder builder)该方法内容是一致的,因此注入方式一致的。
    通过定义IDependency空接口方式,需要注入的类则继承该接口即可。
    代码如下:

    /// <summary>
    /// 应用程序IOC配置
    /// </summary>
    public class IocConfig : ConfigBase
    {
        // 重写加载配置
        protected override void Load(ContainerBuilder builder)
        {
            var assembly = this.GetType().GetTypeInfo().Assembly;
            builder.RegisterType<LoggingInterceptor>();
            builder.RegisterAssemblyTypes(assembly)
                .Where(type => typeof(IDependency).IsAssignableFrom(type) && !type.GetTypeInfo().IsAbstract)
                .AsImplementedInterfaces()
                .InstancePerLifetimeScope()
                .EnableInterfaceInterceptors()
                .InterceptedBy(typeof(LoggingInterceptor));
        }
    }
    

    五、例子

    输出日志如下:

    六、相关源码

    自定义日志组件可参考:JCE.DataCenter.Infrastructure
    实现日志组件可参考:JCE.DataCenter.Logs

  • 相关阅读:
    88. Merge Sorted Array
    87. Scramble String
    86. Partition List
    85. Maximal Rectangle
    84. Largest Rectangle in Histogram
    83. Remove Duplicates from Sorted List
    82. Remove Duplicates from Sorted List II
    81. Search in Rotated Sorted Array II
    80. Remove Duplicates from Sorted Array II
    计算几何——点线关系(叉积)poj2318
  • 原文地址:https://www.cnblogs.com/jianxuanbing/p/7325019.html
Copyright © 2011-2022 走看看