天天看點

C# 用delegate實作AOP事務[C# | AOP | delegate]

前言

正文

     我們先來看一段代碼雛形:

C# 用delegate實作AOP事務[C# | AOP | delegate]

    class testclass

    {

        public void test()

        {

            console.writeline("test");

        }

        public void delegatetest(delegatemethod dm)

            console.writeline("delegatemethod start

C# 用delegate實作AOP事務[C# | AOP | delegate]

");

            dm.invoke();

            console.writeline("delegatemethod end

C# 用delegate實作AOP事務[C# | AOP | delegate]

    }

    class program

        static void main(string[] args)

            testclass tc = new testclass();

            tc.test();

            console.writeline("-------------------------------");

            tc.delegatetest(new delegatemethod(mc.test));

            console.read();

C# 用delegate實作AOP事務[C# | AOP | delegate]

輸出結果

test

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

delegatemethod start...

delegatemethod end...

          我認為這也是一種aop的方式,隻是和傳統的不太一樣,如果把調用方和被調用方看成用戶端和伺服器的話,那麼傳統的aop是施加在伺服器端的,并在伺服器端控制的,而現在我把這個權利交出來,交給用戶端來控制,也就是由調用者來決定是不是要使用事務,也就是調用者自己決定用事務或非事務的方式來執行方法。請注意:如果到這裡你不能接受我的想法請不必往下看了 : )

     接下來我會把代碼貼全,注意代碼我都測試通過了的:  )

     sqldal.cs 把上篇文章拿過來拷貝過來改把改把貼上來

C# 用delegate實作AOP事務[C# | AOP | delegate]

        #region 

        //事務

        private sqltransaction _sqltrans;

        //資料庫連接配接類

        private sqlconnectionstringbuilder _connectionstring = null;

        #endregion

        #region delegate

        /// <summary>

        /// 用于執行帶dictionary參數無傳回值的函數

        /// </summary>

        /// <param name="dict"></param>

        public delegate void void_dictionary_method(dictionary<string, object> dict);

        #region method

        #region executenonquery

        public int executenonquery(string cmdtext)

            if (sqltrans == null)

                return sqlhelper.executenonquery(connectionstring.connectionstring, commandtype.text, cmdtext);

            else

                return sqlhelper.executenonquery(sqltrans, commandtype.text, cmdtext);

        public int executenonquery(string cmdtext, commandtype type)

                return sqlhelper.executenonquery(connectionstring.connectionstring, type, cmdtext);

                return sqlhelper.executenonquery(sqltrans, type, cmdtext);

        public int executenonquery(string cmdtext, commandtype type, params sqlparameter[] cmdparameters)

                return sqlhelper.executenonquery(connectionstring.connectionstring, type, cmdtext, cmdparameters);

                return sqlhelper.executenonquery(sqltrans, type, cmdtext, cmdparameters);

        /// 在事務中執行

        /// <param name="action"></param>

        /// <param name="args"></param>

        public void transactionaction(delegate delegatemethod, params object[] args)

            sqlconnection sqlconnect = new sqlconnection(connectionstring.connectionstring);

            sqlconnect.open();

            _sqltrans = sqlconnect.begintransaction();

            try

            {

                //資料庫操作

                delegatemethod.dynamicinvoke(args);

                //送出事務

                _sqltrans.commit();

            }

            catch (sqlexception)

                _sqltrans.rollback();

                //日志

            finally

                if (sqltrans != null)

                {

                    _sqltrans.dispose();

                    _sqltrans = null;

                }

                if (sqlconnect != null)

                    sqlconnect.close();

        #region properties

        /// 僅支援有事務時操作

        public sqltransaction sqltrans

            get { return _sqltrans; }

            set { _sqltrans = value; }

        /// 字元串連接配接

        public virtual sqlconnectionstringbuilder connectionstring

            get

                if (_connectionstring == null || string.isnullorempty(_connectionstring.connectionstring))

                    _connectionstring = new sqlconnectionstringbuilder(configurations.sqlserver_connection_string);

                return _connectionstring;

            set { _connectionstring = value; }

C# 用delegate實作AOP事務[C# | AOP | delegate]

     代碼說明:

          1.     講delegate作為參數,我們可以傳任何一個delegate進來,不必使用實際的如void_dictionary_method作為參數傳遞,這對于通用是一個很好的辦法。

          2.     transactionaction方法第二個參數是你要傳遞的參數,即委托的參數。msdn:作為參數傳遞給目前委托所表示的方法的對象數組。- 或 - 如果目前委托所表示的方法不需要參數,則為null。

      userinfoaction.cs 不變

C# 用delegate實作AOP事務[C# | AOP | delegate]

public class userinfoaction:sqldal

{

        public void add(dictionary<string, object> dict)

            stringbuilder sql = new stringbuilder();

            sql.append("insert [userinfo](");

C# 用delegate實作AOP事務[C# | AOP | delegate]
C# 用delegate實作AOP事務[C# | AOP | delegate]

            executenonquery(sql);

}

C# 用delegate實作AOP事務[C# | AOP | delegate]

     main

C# 用delegate實作AOP事務[C# | AOP | delegate]

            dictionary<string, object> dict = new dictionary<string, object>();

            userinfoaction uiaction = new userinfoaction();

            dict.add("username", "abc");

            dict.add("password", "abc");

            dict.add("email", "[email protected]");

            //普通方式執行

            //uiaction.add(dict);

            //事務方式執行

            uiaction.transactionaction(new userinfoaction.void_dictionary_method(uiaction.add), dict);

C# 用delegate實作AOP事務[C# | AOP | delegate]

     代碼說明

          1.     可以看到普通方式和事務方式執行方式不同,但是我們不用改userinfoaction的代碼!!我們在寫代碼尤其是維護的時候就是這樣的原則,或者是增量式開發也是比較好的,盡量不去改是比較好的。

          2.     請注意:你的delegate必須符合method,否則編譯時會出錯的,雖然解決了統一調用的問題,但是這個delegate目前我還沒想到辦法解決,也就是你有一個不同參數、傳回值方法就得對應一個delegate,方法名稱不限制,是以一開始我們就得定義可能好幾十個委托,這也是利弊所在不,不然還是很完美的。

          3.     有朋友可能覺得這個決定權不應該交給用戶端來決定,必須事務,那這也好辦,請看代碼:

C# 用delegate實作AOP事務[C# | AOP | delegate]

    public class userinfoaction:sqldal

            transactionaction(new void_dictionary_method(_add), dict);

        private void _add(dictionary<string, object> dict)

            userinfo uinfo = new userinfo();

            uinfo.setpropertyvalue(dict);

            insert(uinfo);

C# 用delegate實作AOP事務[C# | AOP | delegate]

          而我們用戶端代碼又可以切換成普通方式調用了,但實際上他已經處在事務當中了。

比較與特點

     相比attribute實作aop事務,有以下幾個特點:

     1.     delegate方式效率肯定要比attribute方式高,看看他執行個體化多少個類加上多少次反射就知道了。

     2.     delegate方式我們可以對錯誤進行catch處理.

     3.     delegate方式得定義盡可能多的方法形式,這點比較不友善。

結束

     一天半的時間又沒了,但是又多了一種解決方案,我相信沒有最好的解決方案,隻有更好的解決方案,是以我希望當有人問你一個問題的時候,尤其是學習,你盡可能的給出多個方案并幫助他分析各個方案的利弊。歡迎大家提建議 : )

轉載:http://www.cnblogs.com/over140/archive/2009/01/09/1372255.html