我之前寫一篇關於事件訂閱的文章(事件的好處~實現對修改的封閉,對擴展的開放!~續),但它主要是訂閱靜態事件,而今天主要講的是實例事件,即,當一個事件發布者被實例化后,去訂閱它里面的事件,然后當這個事件發布者去觸發該事件時,自己執行你訂閱的內容,這沒什么可說的,一切都很正常。
但在B/s系統中,常常都有這樣一種需求,即:Order類中有方法GeneratorOrder,即生成訂單的方法,這個方法會被UI層的很多方法調用,以實現對不同業務產品的購買,如:購買家電產品,購買成功后應該去和家電有關的成功頁;而購買日常用品,成功后應該去與日常用戶相關的頁面;以后還會有其它業務產品的成功頁,需要我們去實現。
作法1:用static event,靜態事件,但有一個問題,由於它是對類而言的事件,所以A用戶訂閱的事件,在B用戶通過瀏覽器查看時,也會訂閱這個事件,所以,靜態事件不能滿足我們的要求(一般用靜態事件做全局性的工作)
作法2:直接把所有產品所對應的成功頁寫在Generatororder方法里,通過switch去分別處理;這種作法可以解決這個問題,但這樣的程序沒有任何的可擴展性而言,也不是真正面向對象的程序。
作法3:使用普通事件,在產品A訂閱完成事件后,將事件發布者以參數的形式,傳遞給generatororder方法,這就一種最標准,更可靠的作法。
代碼如下:
1 /// <summary> 2 /// 事件發布者 3 /// </summary> 4 public partial class ReturnMsgClass 5 { 6 partial void OnLoad(); 7 public ReturnMsgClass() 8 { 9 OnLoad(); 10 } 11 12 #region Events 13 /// <summary> 14 /// 返回消息事件[實例事件] 15 /// </summary> 16 public event Func<string> ReturnMsg; 17 #endregion 18 19 #region OnEvents Methods 20 /// <summary> 21 /// 觸發ReturnMsg事件 22 /// </summary> 23 public string OnReturnMsg() 24 { 25 if ((this.ReturnMsg != null)) 26 { 27 return this.ReturnMsg(); 28 } 29 else 30 return "沒有訂閱事件"; 31 } 32 #endregion 33 }
下面是事件的訂閱者,它應該傳入的事件發布者對象,去訂閱相應的事件
1 /// <summary> 2 /// 事件訂閱者 3 /// </summary> 4 public class Subscriber 5 { 6 public Subscriber(ReturnMsgClass returnMsgClass, string url) 7 { 8 returnMsgClass.ReturnMsg += delegate() { return url; }; 9 } 10 }
而對於A類產品在購買成功后,然后執行一些邏輯
1 public partial class HomeController 2 { 3 public ActionResult Test() 4 { 5 ReturnMsgClass rm = new ReturnMsgClass(); 6 Subscriber sub = new Subscriber(rm, "http://www.sina.com");//如果訂閱成功,就將這個地址返回 7 return View("Index", rm); 8 } 9 }
而在購買成功頁,將會有這樣的重定向的邏輯
1 @{ 2 Response.Redirect((Model as TEstMv3.Controllers.ReturnMsgClass ?? new TEstMv3.Controllers.ReturnMsgClass()).OnReturnMsg()); 3 }
最后,實現的效果就是,當用戶訪問test頁面時,事件后訂閱,然后自動跳轉到指定的頁面。