代碼說明:
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"; } } }