C#使用KingAOP实现AOP面向切面编程二
本文继续上篇讲述一下比较复杂点的AOP例子,先新建一个控制台项目,然后同样先在Nuget中搜索安装KingAop到项目中
1、项目结构
2 、定义一个登录实体类User和LoggingAspect切面日志类
public class User { public int ID { get; set; } public string Name { get; set; } public string Pwd { get; set; } public string State { get; set; } public System.DateTime LoginTime { get; set; } }
/// <summary> /// 创建一个日志切面处理类 /// </summary> public class LoggingAspect : OnMethodBoundaryAspect { public override void OnEntry(MethodExecutionArgs args) { string logData = CreateLogData("entering", args); Console.WriteLine(logData); } public override void OnException(MethodExecutionArgs args) { string logData = CreateLogData("exception", args); Console.WriteLine(logData); } public override void OnSuccess(MethodExecutionArgs args) { string logData = CreateLogData("success", args); Console.WriteLine(logData); } public override void OnExit(MethodExecutionArgs args) { string logData = CreateLogData("exiting", args); Console.WriteLine(logData); } /// <summary> /// AOP处理登录日志逻辑,只需在此进行修改即可,无需修改被切面的处理类 /// </summary> /// <param name="methodStage"></param> /// <param name="args"></param> /// <returns></returns> private string CreateLogData(string methodStage, MethodExecutionArgs args) { var str = new StringBuilder(); str.AppendLine(); str.AppendLine(string.Format(methodStage + " {0} ", args.Method)); foreach (var argument in args.Arguments) { //下面利用反射机制获取对象名称和对象属性和属性值 var argType = argument.GetType(); str.Append(argType.Name + ": "); if (argType == typeof(string) || argType.IsPrimitive) { str.Append(argument); } else { foreach (var property in argType.GetProperties()) { str.AppendFormat("{0} = {1}; ", property.Name, property.GetValue(argument, null)); } } } return str.ToString(); } }
3、定义一个登录业务类Login,并且继承IDynamicMetaObjectProvider类
/// <summary> /// 该类需要继承IDynamicMetaObjectProvider,因为KingAOP是基于动态类型进行操作和绑定的,如不继承是不会进入到刷选器中的相应事件里 /// 登录功能,只需添加一个LoggingAspect即可实现日志功能,达到业务逻辑和通用处理逻辑的分离 /// </summary> public class Login : IDynamicMetaObjectProvider { //添加处理日志切面 [LoggingAspect] public void LoginValdate(User entity) { //只需进行业务逻辑处理,无需进行日志处理,日志处理交给切面处理 if (entity.Name == "jack" && entity.Pwd == "wang") { entity.State = "Logged"; } else { entity.State = "Error"; } } /// <summary> /// 该类必须实现IDynamicMetaObjectProvider的GetMetaObject方法 /// </summary> /// <param name="parameter"></param> /// <returns></returns> public DynamicMetaObject GetMetaObject(Expression parameter) { return new AspectWeaver(parameter, this); } }
4、接下来就是测试代码,如下
class Program { static void Main(string[] args) { //复杂例子 Login test = new Login(); dynamic entity = new User { ID = 99, Name = "Jon", Pwd = "wang", State = "", LoginTime = System.DateTime.Now }; test.LoginValdate(entity); Console.Read(); } }