zoukankan      html  css  js  c++  java
  • postsharp初体验

    首先,有必要先介绍下,什么叫做AOP(Aspect-Oriented Programming,面向切面编程)。下图是百度的词条解释

    用图来解释可能更直接了当些:

    image

    ps:图片来自http://www.cnblogs.com/leoo2sk/archive/2010/11/30/aop-postsharp.html

    简单的说,AOP是一种独立于系统业务逻辑的贯穿整个系统的横切关注点,比如异常处理,日志的记录等。

    --------------------------------------------------------------------------------------------------------------------------

    之前在项目中,经常碰到的问题是:如何给所有的方法都加上一个统一的异常处理的方法,特别是cs模式的(bs模式比较简单,可以通过在Global文件中捕获异常,并记录)。另外之前面试时,也被问到类似的问题,当时我思考了很长时间,还是想不出什么好的办法。后来今天看MVC4 web编程一书时,文中提到可以通过特性来统一记录异常日志。于是,我欣喜若狂,赶紧百度相关的技术的文章,发现了一个非常好用的AOP的插件,也就是这篇文章的主角:PostSharp

    1. 下载PostSharp(https://www.postsharp.net/)。现在版本已经更新到4.1。1.5是免费的,大于2.0的版本都是收费的。我下了个3.0的版本及其keygen。有需要的加我q(371323761)

    2. 安装PostSharp。过程很简单,按照其流程即可。按照后,打开keygen,生成License即可。

    3. 打开vs,右键项目,选择Add PostSharp to project,如下图,接下来便可以用PostSharp来写些AOP的应用了

    ----------------------------------------------------------------------------------------------------------------

    比如我们想对每个类的每个方法做异常日志记录

    1. 定义日志记录类

    namespace CustomAttribute
    {
        public interface ILog
        {
            void log(string msg);
        }
    }
    [Serializable]
        public class Logger:ILog
        {
            public void log(string msg)
            {
                string path = Environment.CurrentDirectory + "\" + string.Format("systemlog/{0}/{1}/{2}", "error", DateTime.Now.Year, DateTime.Now.Month);
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
                string logPath = path + "/" + DateTime.Today.ToString("yyyy-MM-dd") + ".txt";
                if (!File.Exists(logPath))
                {
                    var file = File.Create(logPath);
                    file.Close();
                }
                StreamWriter sw = new StreamWriter(logPath, true);
                sw.WriteLine(msg);
                sw.Flush();
                sw.Close();
            }
        }

    2. 定义异常日志记录的特性

    [Serializable]
        [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
        public class ExceptionLogAttribute : OnMethodBoundaryAspect
        {
            private ILog logger;//通过依赖注入的方式解耦
    
            public ExceptionLogAttribute(ILog log)
            {
                logger = log;
            }
    
            public override void OnException(MethodExecutionArgs args)
            {
                base.OnException(args);
                logger.log(string.Format("{0}:{1}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), args.Exception.Message));
            }
        }
    [Serializable]
        [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]//AttributeTargets.Method说明该特性是应用到方法上的
    public sealed class MyExceptionLogAttribute:ExceptionLogAttribute { public MyExceptionLogAttribute() : base(new Logger()) { } }

    3. 应用特性到方法上

    class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine(Divide(1, 0));
                Console.ReadLine();
            }
    
            [MyExceptionLog]
            private static int Divide(int a, int b)
            {
                return a / b;
            }
    
        }

    4. 结果

    PostSharp还有很多用处,日后再慢慢挖掘。

    很喜欢PostSharp官网上的一句话:

    Start writing cleaner code today!

    以前写代码总是关注于如何实现功能,后来慢慢学会用设计模式重构代码,现在懂得了AOP(postsharp),便可以从另外一个角度,以更优雅的方式写代码。

     ------------------------

    问题1:如果想对类的所有方法定义统一的异常日志记录的特性,怎么办呢?

    如果把特性Targets定义为All或class,可以捕获该类的所有的方法的异常

    问题2:如果想对程序集(dll)中每个方法定义异常日志记录的特性,怎么呢?

    把特性的Targets定义为all或Assembly,然后在AssemblyInfo.cs文件中,新增程序集的特性

  • 相关阅读:
    C#开发Activex控件疑难杂症
    spring、struts、mybatis、Postgresql集成使用存储过程进行分页
    C#开发Activex控件升级
    通过Maven将Web程序部署到远程Tomcat8服务器的一些注意事项
    分页存储过程Oracle版
    JSP EL表达式(转)
    关于Log4x
    C#类在初始化时的执行顺序
    使用MSMQ 远程队列
    tomcat部署与Context(转)
  • 原文地址:https://www.cnblogs.com/xingluzhe/p/4738150.html
Copyright © 2011-2022 走看看