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 = ; 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,而且监控方法名 参数值 执行结果 想想都觉得棒~~
最新文章
- 有关windows系统的EXE和DLL文件说法错误
- opnet学习过程
- [ZZ] HDR&;ToneMapping
- 常用的DC插头公头的尺寸
- 在usercontrol中如何使用验证控件CustomValidator 中的客户端验证
- Install SharePoint 2013 on Windows Server 2012 without a domain
- Redis缓存实现单点登录SSO
- C库函数标准编程之fscanf()函数解读及其实验
- 进程间通信系列 之 消息队列函数(msgget、msgctl、msgsnd、msgrcv)及其范例
- 基于node的websocket示例
- PHP 5 常量
- 【linux】工作时使用的命令
- python之路——8
- codeforces 251 div2 D. Devu and his Brother 三分
- 多线程实现ping扫描
- EL和自定义函数库
- Nginx unknown directive ";";
- 申请免费通配符证书(Let&#39;s Encrypt)并绑定IIS(转载)
- 【TRICK】[0,n)中所有大小为k的子集的方法
- The Collections Module内建collections集合模块