前言
正文
我們先來看一段代碼雛形:

class testclass
{
public void test()
{
console.writeline("test");
}
public void delegatetest(delegatemethod dm)
console.writeline("delegatemethod start
");
dm.invoke();
console.writeline("delegatemethod end
}
class program
static void main(string[] args)
testclass tc = new testclass();
tc.test();
console.writeline("-------------------------------");
tc.delegatetest(new delegatemethod(mc.test));
console.read();

輸出結果
test
-------------------------------
delegatemethod start...
delegatemethod end...
我認為這也是一種aop的方式,隻是和傳統的不太一樣,如果把調用方和被調用方看成用戶端和伺服器的話,那麼傳統的aop是施加在伺服器端的,并在伺服器端控制的,而現在我把這個權利交出來,交給用戶端來控制,也就是由調用者來決定是不是要使用事務,也就是調用者自己決定用事務或非事務的方式來執行方法。請注意:如果到這裡你不能接受我的想法請不必往下看了 : )
接下來我會把代碼貼全,注意代碼我都測試通過了的: )
sqldal.cs 把上篇文章拿過來拷貝過來改把改把貼上來

#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; }

代碼說明:
1. 講delegate作為參數,我們可以傳任何一個delegate進來,不必使用實際的如void_dictionary_method作為參數傳遞,這對于通用是一個很好的辦法。
2. transactionaction方法第二個參數是你要傳遞的參數,即委托的參數。msdn:作為參數傳遞給目前委托所表示的方法的對象數組。- 或 - 如果目前委托所表示的方法不需要參數,則為null。
userinfoaction.cs 不變

public class userinfoaction:sqldal
{
public void add(dictionary<string, object> dict)
stringbuilder sql = new stringbuilder();
sql.append("insert [userinfo](");
executenonquery(sql);
}

main

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);

代碼說明
1. 可以看到普通方式和事務方式執行方式不同,但是我們不用改userinfoaction的代碼!!我們在寫代碼尤其是維護的時候就是這樣的原則,或者是增量式開發也是比較好的,盡量不去改是比較好的。
2. 請注意:你的delegate必須符合method,否則編譯時會出錯的,雖然解決了統一調用的問題,但是這個delegate目前我還沒想到辦法解決,也就是你有一個不同參數、傳回值方法就得對應一個delegate,方法名稱不限制,是以一開始我們就得定義可能好幾十個委托,這也是利弊所在不,不然還是很完美的。
3. 有朋友可能覺得這個決定權不應該交給用戶端來決定,必須事務,那這也好辦,請看代碼:

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);

而我們用戶端代碼又可以切換成普通方式調用了,但實際上他已經處在事務當中了。
比較與特點
相比attribute實作aop事務,有以下幾個特點:
1. delegate方式效率肯定要比attribute方式高,看看他執行個體化多少個類加上多少次反射就知道了。
2. delegate方式我們可以對錯誤進行catch處理.
3. delegate方式得定義盡可能多的方法形式,這點比較不友善。
結束
一天半的時間又沒了,但是又多了一種解決方案,我相信沒有最好的解決方案,隻有更好的解決方案,是以我希望當有人問你一個問題的時候,尤其是學習,你盡可能的給出多個方案并幫助他分析各個方案的利弊。歡迎大家提建議 : )
轉載:http://www.cnblogs.com/over140/archive/2009/01/09/1372255.html