AOP Using Spring.NET

閱讀CodeProject的AOP Using Spring.NET(Part 1 , Part 2)整理下來。

CodeProject的AOP Using Spring.NET(Part 1Part 2),用簡單的說明如何透過Spring.NET來使用AOP。

前篇說明中,就是再加入實作IMethodInterceptor介面的Class,然後在config檔中定義AOP Advice的Target物件及Advice的物件(可以多個,或是沒半個!請看config中的list清單)。

以下是config及專案的架構,AOP專案裡有TraceAroundAdvice及TraceAroundAdvice2兩個Advice物件。

image

而程式中,就把原先是用DI的定義,現在改用AOP的定義,如下appContext["CustomerBLL"]=>appContext["CustomerBLLWithAdvice"]。

private void BindCustomer()
{
    IApplicationContext appContext = ContextRegistry.GetContext();
    //IBLL customerBLL = appContext["CustomerBLL"] as IBLL;
    IBLL customerBLL = appContext["CustomerBLLWithAdvice"] as IBLL;
    GridView1.DataSource = customerBLL.GetAll();
    GridView1.DataBind();
}

AOP專案程式如下,TraceAroundAdvice是寫到事件顯示器之中,TraceAroundAdvice2是透過Debug物件WriteLine出來,

namespace AOP
{
    public class SysConcerns
    {

        # region Write Event Log.....

        /// <summary>
        /// 呼叫Method前Log
        /// </summary>
        /// <param name="invocation"></param>
        public static void EnterLog(IMethodInvocation invocation)
        {
            Write2EventLog(DateTime.Now.ToString("yyyy/MM/dd hh:m:ss") 
            + " Entering " + GetInvokeLog(invocation));
        }

        /// <summary>
        /// 呼叫Method後Log
        /// </summary>
        /// <param name="invocation"></param>
        public static void ExitLog(IMethodInvocation invocation)
        {
            Write2EventLog(DateTime.Now.ToString("yyyy/MM/dd hh:m:ss") 
            + " Exiting " + GetInvokeLog(invocation));
        }

        /// <summary>
        /// 寫入事件顯示器之中
        /// </summary>
        /// <param name="msg"></param>
        private static void Write2EventLog(string msg)
        {
            string src = "AOP Logs";
            string log = "Application";
            if (EventLog.SourceExists(src) == false)
            {
                EventLog.CreateEventSource(src, log);
            }
            EventLog.WriteEntry(src, msg);
        }

        # endregion

        # region Write Console Log.....
        /// <summary>
        /// 呼叫Method前Log Console
        /// </summary>
        /// <param name="invocation"></param>
        public static void EnterLogDebug(IMethodInvocation invocation)
        {
            System.Diagnostics.Debug.WriteLine(DateTime.Now.ToString("yyyy/MM/dd hh:m:ss") 
            + " Entering " + GetInvokeLog(invocation));
        }

        /// <summary>
        /// 呼叫Method後Log Console
        /// </summary>
        /// <param name="invocation"></param>
        public static void ExitLogDebug(IMethodInvocation invocation)
        {
            System.Diagnostics.Debug.WriteLine(DateTime.Now.ToString("yyyy/MM/dd hh:m:ss") 
            + " Exiting " + GetInvokeLog(invocation));
        }
        # endregion

        /// <summary>
        /// 組出呼叫的Method及參數
        /// </summary>
        /// <param name="invocation"></param>
        /// <returns></returns>
        public static string GetInvokeLog(IMethodInvocation invocation)
        {
            string str = invocation.Target.GetType().ToString() + "." + invocation.Method; 
               
            int i = 0;
            if (invocation.Arguments != null)
            {
                str +=  "(";
                foreach (object o in invocation.Arguments)
                {
                    if (i > 0)
                        str = str + ", ";
                    str = str + o.ToString();
                }
                str = str + ")";
            }
            return str;
        }

        
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using AopAlliance.Intercept;


namespace AOP
{
    public class TraceAroundAdvice : IMethodInterceptor 
    {

        public object Invoke(IMethodInvocation invocation)
        {
            //執行前寫Log
            SysConcerns.EnterLog(invocation);
            //實際執行
            object returnValue = invocation.Proceed();

            //執行後寫Log
            SysConcerns.ExitLog(invocation);
            return returnValue;
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AopAlliance.Intercept;

namespace AOP
{
    class TraceAroundAdvice2 : IMethodInterceptor
    {

        public object Invoke(IMethodInvocation invocation)
        {
            //執行前寫Log
            SysConcerns.EnterLogDebug(invocation);
            //實際執行
            object returnValue = invocation.Proceed();

            //執行後寫Log
            SysConcerns.ExitLogDebug(invocation);
            return returnValue;
        }
    }
}

如果有註冊多個Advice的話,以我的範例CustomerDALWithAdvice來說,順序如下,

TraceAroundAdvice Invoke(SysConcerns.EnterLog(invocation))=>TraceAroundAdvice2 Invoke(SysConcerns.EnterLogDebug(invocation))

=>CustomerDAL.GetAll

=>TraceAroundAdvice2 Invoke(SysConcerns.ExitLogDebug(invocation))=>TraceAroundAdvice Invoke(SysConcerns.ExitLog(invocation))

範例:

參考資料:

AOP Using Spring.NET - Part 1

AOP Using Spring.NET - Part 2

Dynamic Decorator Pattern

Hi, 

亂馬客Blog已移到了 「亂馬客​ : Re:從零開始的軟體開發生活

請大家繼續支持 ^_^