博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于微软企业库的AOP组件(含源码)
阅读量:6319 次
发布时间:2019-06-22

本文共 6121 字,大约阅读时间需要 20 分钟。

软件开发,离不开对日志的操作。日志可以帮助我们查找和检测问题,比较传统的日志是在方法执行前或后,手动调用日志代码保存。但自从AOP出现后,我们就可以避免这种繁琐但又必须要实现的方式。本文是在微软企业库的AOP基础上封装出的组件。注意:是使用2.0版本,因为2.0以上版本是基于Net4.5类库的。好了,废话不多说。如图-1所示

1.项目布局.png

图-1

说明

    logmethodBillModel文件,是记录AOP详细信息

    IBasicCodeService和BasicCodeService是用于测试的接口和实现类

    AopUtil是实现Aop的类,核心代码

 

继续分析代码。

  步骤1,先创建2个特性,用于标记在类和方法上,表示这个类中这个方法需要被Aop记录

///     /// 贴在接口上    ///     public class NSAopHandlerAttribute : HandlerAttribute    {        public override ICallHandler CreateHandler(Microsoft.Practices.Unity.IUnityContainer container)        {            return new NSAopCallHandler();        }    }     ///     /// 贴在方法上,作用:用于开启AOP功能    /// 开启AOP日志保存    ///     public class NSAopMethodToMethodHandlerAttribute : System.Attribute    {    }

  

  步骤2,继承ICallHandler接口实现Aop功能

public class NSAopCallHandler : ICallHandler    {                public int Order { get; set; }        public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)        {            //增加其他日志类型,处理方案如下            //无论是否需记录log_method方法,方法均先执行完成.同时,记录时执行时间            MethodBase mbCurrent = input.MethodBase;            string methodName = input.MethodBase.Name;            string fullName = input.Target.ToString() + "." + methodName;                         //1,方法执行,并记录开始和结束执行时间            DateTime dtmBegin = DateTime.Now;            var methodReturn = getNext()(input, getNext);            DateTime dtmEnd = DateTime.Now;            TimeSpan ts = dtmEnd - dtmBegin;            decimal invokeMilliSecond = Convert.ToDecimal(ts.TotalMilliseconds);                          //6,判断是否需保存Aop日志            object attriToMethod  = AttributeHelper.GetCustomAttribute(mbCurrent, "NSAopMethodToMethodHandlerAttribute");            if (attriToMethod != null    )            {                string declaringType = input.MethodBase.ToString();                string instanceName = input.MethodBase.Module.Name;                //获取参数列表                Dictionary
dicParamInfo = new Dictionary
(); for (var i = 0; i < input.Arguments.Count; i++) { string piName = input.Arguments.ParameterName(i); string piValue = input.Arguments[i] as string; dicParamInfo.Add(piName, piValue); } //获取方法的层级关系 //参考地址:http://www.cnblogs.com/mumuliang/p/3939143.html string parentFullName = null; string parentDeclaringType = null; System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace(); System.Diagnostics.StackFrame[] sfs = st.GetFrames(); for (int u = 0; u < sfs.Length; ++u) { System.Reflection.MethodBase mb = sfs[u].GetMethod(); //数据如下所示 //[CALL STACK][12]: ExampleAOP.AOPProxy.BasicCodeService.DoSomething1 //[CALL STACK][13]: ExampleAOP.AOPProxy.AOPProxyTest.Output //[CALL STACK][14]: ExampleAOP.Program.Main string parentInfo = string.Format("[CALL STACK][{0}]: {1}.{2}", u, mb.DeclaringType.FullName, mb.Name); //判断是否包含本方法.若包含,则获取其下一级的数据即可 string source = mb.Name; if (source == methodName) { if (u + 1 < sfs.Length) { System.Reflection.MethodBase mbParent = sfs[u + 1].GetMethod(); parentFullName = mbParent.DeclaringType.FullName + "." + mbParent.Name; parentDeclaringType = mbParent.ToString(); } break; } } //记录至全局静态变量 logmethodBillModel modelLog = new logmethodBillModel() { MethodName = methodName, FullName = fullName, DeclaringType = declaringType, ParentFullName = parentFullName, ParentDeclaringType = parentDeclaringType, ParamInfo = dicParamInfo, InvokeBeginTime = dtmBegin, InvokeEndTime = dtmEnd, InvokeMilliSecond = invokeMilliSecond, InstanceName = instanceName, }; BaseService.LogMethods.Add(modelLog); } return methodReturn; } }

  

  步骤3,就是对接口的使用,当然这里用的是IOC。如下代码所示

///         /// 创建Service服务类,基于微软企业库        ///         /// 
///
public static T CreateService
() where T : class { IUnityContainer container = new UnityContainer().AddNewExtension
(); container.RegisterType
(); container.Configure
().SetInterceptorFor
(new InterfaceInterceptor()); T t = container.Resolve
(); return t; }

  

好了,搞定收工。看看调用的代码。so easy

class Program    {        static void Main(string[] args)        {            IBasicCodeService baService = BaseService.CreateService
(); string userName = baService.SingleUserCode("user1"); List
listUserCode = baService.GetListUserCode("code1", "name1"); System.Console.WriteLine("生成日志个数:" + BaseService.LogMethods.Count); System.Console.ReadKey(); } }

  

这里有一点要说明下,就是接口中有方法1(需记录Aop);方法2(不需记录)。这种情况下,若方法2引用方法1时,也想生成Aop的话,需这样调用,直接使用this是不行的

public string SingleUserCode(string userCode)        {            IBasicCodeService baService = BaseService.CreateService
(); var listUserCode = baService.GetListUserCode(userCode, "name1"); return listUserCode[0]; } public List
GetListUserCode(string userCode, string userName) { return new List
() { "UserCode1", "UserCode2" }; }

  

介绍AOP比较全面的博客

 

 源码下载方式
1,关注微信公众号:小特工作室(也可直接扫描签名处二维码)
2,发送:示例4008
即可下载 
你可能感兴趣的文章
nfd指令的详细说明
查看>>
安装VisualSvn Server时遇到的问题
查看>>
人脸识别 开放书籍 下载地址
查看>>
Notepad++配置Python开发环境
查看>>
用户组概念 和 挂载 概念
查看>>
AspNetPager控件的最基本用法
查看>>
sessionKey
查看>>
高性能Javascript--脚本的无阻塞加载策略
查看>>
Java 编程的动态性, 第4部分: 用 Javassist 进行类转换--转载
查看>>
完毕port(CompletionPort)具体解释 - 手把手教你玩转网络编程系列之三
查看>>
iOS8 Push Notifications
查看>>
各大名企笔试及面经大全(程序猿必读)
查看>>
Oracle 连接、会话数的查看,修改
查看>>
Oracle 11g password过期被锁定报道 ORA-28000 the account is locked
查看>>
轨磁条简介
查看>>
NSQ部署
查看>>
大厂前端高频面试问题与答案精选
查看>>
如何设计高扩展的在线网页制作平台
查看>>
Git 2.5增加了工作树、改进了三角工作流、性能等诸多方面
查看>>
深度揭秘腾讯云低功耗广域物联网LPWAN 技术及应用
查看>>