postsharp初體驗

首先,有必要先介紹下,什麼叫作AOP(Aspect-Oriented Programming,面向切面編程)。下圖是百度的詞條解釋
html

用圖來解釋可能更直接了當些:web

image

ps:圖片來自http://www.cnblogs.com/leoo2sk/archive/2010/11/30/aop-postsharp.html面試

簡單的說,AOP是一種獨立於系統業務邏輯的貫穿整個系統的橫切關注點,好比異常處理,日誌的記錄等。編程

--------------------------------------------------------------------------------------------------------------------------設計模式

以前在項目中,常常碰到的問題是:如何給全部的方法都加上一個統一的異常處理的方法,特別是cs模式的(bs模式比較簡單,能夠經過在Global文件中捕獲異常,並記錄)。另外以前面試時,也被問到相似的問題,當時我思考了很長時間,仍是想不出什麼好的辦法。後來今天看MVC4 web編程一書時,文中提到能夠經過特性來統一記錄異常日誌。因而,我欣喜若狂,趕忙百度相關的技術的文章,發現了一個很是好用的AOP的插件,也就是這篇文章的主角:PostSharpide

1. 下載PostSharp(https://www.postsharp.net/)。如今版本已經更新到4.1。1.5是免費的,大於2.0的版本都是收費的。我下了個3.0的版本及其keygen。有須要的加我q(371323761)post

2. 安裝PostSharp。過程很簡單,按照其流程便可。按照後,打開keygen,生成License便可。spa

3. 打開vs,右鍵項目,選擇Add PostSharp to project,以下圖,接下來即可以用PostSharp來寫些AOP的應用了.net

----------------------------------------------------------------------------------------------------------------插件

好比咱們想對每一個類的每一個方法作異常日誌記錄

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文件中,新增程序集的特性

相關文章
相關標籤/搜索