程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C#用Attribute實現AOP事務(4)

C#用Attribute實現AOP事務(4)

編輯:關於C語言

代碼說明:

1.在上面兩篇文章中都是把IContextProperty, IContributeObjectSink單獨繼承並實現的,其實我們發現ContextAttribute已經繼承了IContextProperty,所有這裡我僅僅只需要再繼承一下IContributeObjectSink就行了。關於這兩個接口的說明,上面文章中都有詳細的說明。

2.TransactionAop將在後面給出。

3.需要注意的是兩個Attribute需要一起用,並且我發現Attribute如果標記在類上他會被顯示的實例化,但是放在方法上就不會,打斷點可以跟蹤到這一過程,要不然我也不會費力氣弄兩個來標注了。

TransactionAop.cs

public sealed class TransactionAop : IMessageSink
    {
        private IMessageSink nextSink; //保存下一個接收器
        /// <summary>
        /// 構造函數
        /// </summary>
        /// <param name="next">接收器</param>
        public TransactionAop(IMessageSink nextSink)
        {
            this.nextSink = nextSink;
        }
        /// <summary>
        ///  IMessageSink接口方法,用於異步處理,我們不實現異步處理,所以簡單返回null,
        ///  不管是同步還是異步,這個方法都需要定義
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="replySink"></param>
        /// <returns></returns>
        public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
        {
            return null;
        }
        /// <summary>
        /// 下一個接收器
        /// </summary>
        public IMessageSink NextSink
        {
            get { return nextSink; }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public IMessage SyncProcessMessage(IMessage msg)
        {
            IMessage retMsg = null;
            IMethodCallMessage call = msg as IMethodCallMessage;
            if (call == null ||  (Attribute.GetCustomAttribute(call.MethoDBase, typeof(TransactionMethodAttribute))) == null)
                retMsg = nextSink.SyncProcessMessage(msg);
            else
            {
                //此處換成自己的數據庫連接
                using (SqlConnection Connect = new SqlConnection(Configurations.SQLSERVER_CONNECTION_STRING))
                {
                    Connect.Open();
                    SqlTransaction SqlTrans = Connect.BeginTransaction();
                    //講存儲存儲在上下文
                    CallContext.SetData(TransactionAop.ContextName, SqlTrans);
                    //傳遞消息給下一個接收器 - > 就是指執行你自己的方法
                    retMsg = nextSink.SyncProcessMessage(msg);
                    if (SqlTrans != null)
                    {
                        IMethodReturnMessage methodReturn = retMsg as IMethodReturnMessage;
                        Exception except = methodReturn.Exception;
                        if (except != null)
                        {
                            SqlTrans.Rollback();
                            //可以做日志及其他處理
                        }
                        else
                        {
                            SqlTrans.Commit();
                        }
                        SqlTrans.Dispose();
                        SqlTrans = null;
                    }
                }
            }
            return retMsg;
        }
        /// <summary>
        /// 用於提取、存儲SqlTransaction
        /// </summary>
        public static string ContextName
        {
            get { return "TransactionAop"; }
        }
    }
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved