zoukankan      html  css  js  c++  java
  • AOP实战(1)

    AOP在MVC中有广泛的应用 如:IActionFilter、 IAuthenticationFilter、 IAuthorizationFilter、IExceptionFilter、IResultFilter

    熟悉MVC的人对这些过滤器已经是运用自如了

    下面说下在项目中如何监控自己自定义类的方法 或者接口,本文结合Autofac 做一些介绍:

    这里需要几个Nuget包:

    Autofac;

    Castle.DynamicProxy;

    Autofac.Extras.DynamicProxy;

    DynamicProxy 可以监控接口以及类这里对监控接口做了一个例子:

    /// <summary>
        /// liyouming  Add  20170914 AOP 拦截器
        /// </summary>
    
        public class LoggerAttribute : IInterceptor
        {
    
            private IDAL_TbSysOperatorLog _operatorLogs;
    
    
            public LoggerAttribute(IDAL_TbSysOperatorLog operatorLogs)
            {
                _operatorLogs = operatorLogs;
    
    
            }
            public void Intercept(IInvocation invocation)
            {
    
                var LogMethod = invocation.Method.GetCustomAttribute(typeof(LogMethodAttribute), false) as LogMethodAttribute;
                if (LogMethod != null)
                {
                    var userinfo = HttpContext.Current.User as ClaimsPrincipal;
                    string name = invocation.Method.Name;
                    var mappedParameters = MapParameters(invocation.Arguments, invocation.Method.GetParameters())
                    .ToDictionary(x => x.Key, x => x.Value.ToString());
                    string parameters = JsonConvert.SerializeObject(mappedParameters);
                    Stopwatch watch = Stopwatch.StartNew();
                    invocation.Proceed();
                    string exectime = watch.ElapsedMilliseconds.ToString();
                    string returnValue = JsonConvert.SerializeObject(invocation.ReturnValue);
                    _operatorLogs.Insert_TbSysOperatorLogAsync(new TbSysOperatorLog { CreateID = userinfo.FindFirst("sub").Value, CreateName = userinfo.FindFirst("user_name").Value, OperatorResult = returnValue, ClassMoudle = invocation.InvocationTarget.ToString(), OperatorMethod = name, OperatorParameters = parameters, ExecTime = exectime, Description = LogMethod.Option, IP = HttpContext.Current.Request.UserHostAddress });
                }
            }
            public IEnumerable<KeyValuePair<string, object>> MapParameters(object[] arguments, ParameterInfo[] getParameters)
            {
                for (int i = 0; i < arguments.Length; i++)
                {
                    var obj = JsonConvert.SerializeObject(arguments[i]);
                    yield return new KeyValuePair<string, object>(getParameters[i].Name, obj);
    
                }
            }
        }

    上述代码是结合 Owin中间件授权 加上 Autofac注入

    在注入LoggerAttribute之前首先要注入相关的接口服务  IDAL_TbSysOperatorLog 是我的操作日志服务 ,在构造函数中加入对 IDAL_TbSysOperatorLog的依赖,然后结合Owin中间件中的信息,获取对应操作人员,之前也被AOP中如何获取日志操作人犯愁,后面发现这样做对了

    Autofac注入相关代码:

      builder.RegisterAssemblyTypes(AppDomain.CurrentDomain.GetAssemblies())
                             .Where(t => t.GetCustomAttribute<DependencyRegisterAttribute>() != null)
                             .AsImplementedInterfaces().EnableInterfaceInterceptors()
                             .InstancePerLifetimeScope();
                builder.RegisterType<LoggerAttribute>().InstancePerLifetimeScope();
                builder.RegisterType<ExecTimeAttribute>().InstancePerLifetimeScope();

    .EnableInterfaceInterceptors() 这是允许设置监控接口

    .EnableClassInterceptors() 是允许设置监控类

    根据实际项目情况设置

    builder.RegisterType<LoggerAttribute>().InstancePerLifetimeScope();
    
    //注册我们自定义的监控方法,实现IInterceptor就行了 

    这里设置监控的方法,类名称、参数值、执行时间、ip、方法返回值 等等

     因为这里IInterceptor属性只能定义 类或者接口 那么对于接口或者类中的所有方法都会监控,怎么去除掉不必要的方法监控

    自定义一个方法属性:设置属性只能用在方法上,这样含有该属性的方法就能写日志,日志一般会有描述(如:业务功能描述) 所以这里我加入了一个Option 

     [AttributeUsage(AttributeTargets.Method)]
        public class LogMethodAttribute : Attribute
        {
            private string _option;
            public LogMethodAttribute()
            {
                _option = "";
            }
            public LogMethodAttribute(string Option)
            {
    
                _option = Option;
            }
    
            public string Option
            {
                get
                {
    
                    return _option;
                }
                set {
                    _option = value;
                }
    
            }
        }
    下面看看接口中的写法:
     [Intercept(typeof(LoggerAttribute))]
        public interface IBLL_TESTServices
        {
    
            [LogMethod(Option = "添加测试用例")]
            Task<OperationResult> AddTEST(TESTModel model);
    
    
            List<dynamic> GetPremission(string guid);
        }
    接口中有两个方法,这里只监控了 AddTEST 方法 并产生操作日志,这里我里面的操作日志最好用异步

    接下来测试下:查看数据库中数据

    至此依然搞定,AOP 使我的代码耦合性降低了,我们不用在每个方法中去写很多方法,面向切面编程只需要写属性就ok,而且监控方法名 参数值  执行结果  想想都觉得棒~~

    
    





  • 相关阅读:
    tomcat加载项目原理解惑
    英语口语大全
    ubuntu中wubi正在下载ubuntu11.04desktopi386.iso
    Strust2获得session和request
    字符串转成对象
    DevExpress控件使用
    DevExpress控件之GridControl控件(控件篇)
    ASP.NET AJAX + JSON 实现对象调用
    WinForm窗体之间交互的一些方法[转]
    barmanager设置
  • 原文地址:https://www.cnblogs.com/liyouming/p/7526365.html
Copyright © 2011-2022 走看看