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,而且监控方法名 参数值 执行结果 想想都觉得棒~~
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!
本文版权归作者和博客园共有,来源网址:http://www.cnblogs.com/liyouming欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接。