一.nop事件機制簡介

應(yīng)用場景:客戶支付成功后,需要發(fā)送短信、郵件告知客戶訂單支付成功(短信、郵件由不同模塊實現(xiàn))

實現(xiàn)方法: 1.定義支付成功OrderPaidEvent事件。

               2.定義短信,郵箱兩個消費者共同監(jiān)聽OrderPaidEvent事件,并實現(xiàn)相關(guān)業(yè)務(wù)。

               3.當(dāng)客戶支付成功后生產(chǎn)者發(fā)送OrderPaidEvent事件。

               4.消費者接收到OrderPaidEvent事件后,短信和郵箱消費者分別執(zhí)行自己的業(yè)務(wù)。

     nop事件機制使用到“生產(chǎn)者/消費者”模式。生產(chǎn)者只負(fù)責(zé)發(fā)布事件,并不需要關(guān)心誰來處理,相反消費者只用來處理事件。那生產(chǎn)者和消費者是如何進行關(guān)聯(lián)的呢?nop實現(xiàn)是非常簡單的,通過泛型來定義一個事件類,如果生產(chǎn)者和消費者都使用同一個事件類,那么就關(guān)聯(lián)到一起了稱之為訂閱。負(fù)責(zé)實現(xiàn)事件機制的部分稱之為緩沖區(qū),緩沖區(qū)的作用是通過解耦的方式實現(xiàn)消息機制。生產(chǎn)者和消費者是一對多的關(guān)系。下圖簡單介紹下生產(chǎn)者消費者關(guān)系。

大數(shù)據(jù)培訓(xùn),云培訓(xùn),數(shù)據(jù)挖掘培訓(xùn),云計算培訓(xùn),高端軟件開發(fā)培訓(xùn),項目經(jīng)理培訓(xùn)

二.nop事件相關(guān)接口

生產(chǎn)者接口:Nop.Services.Events.IEventPublisher

消費者接口:Nop.Services.Events.IConsumer<T>

事件訂閱接口:Nop.Services.Events.ISubscriptionService

IEventPublisher接口Publish<T>(T eventMessage)方法用于發(fā)布事件(生產(chǎn)者)。

IConsumer<T>接口HandleEvent(T eventMessage)方法用于處理事件(消費者)。

兩者之間的關(guān)系由T泛型來關(guān)聯(lián),稱之為事件,簡單的說T類型相同則兩者關(guān)聯(lián)訂閱成功。

ISubscriptionService接口GetSubscriptions<T>()方法返回IList<IConsumer<T>>集合,該集合保存了消費者。

接口實現(xiàn)如下圖:

大數(shù)據(jù)培訓(xùn),云培訓(xùn),數(shù)據(jù)挖掘培訓(xùn),云計算培訓(xùn),高端軟件開發(fā)培訓(xùn),項目經(jīng)理培訓(xùn)

大數(shù)據(jù)培訓(xùn),云培訓(xùn),數(shù)據(jù)挖掘培訓(xùn),云計算培訓(xùn),高端軟件開發(fā)培訓(xùn),項目經(jīng)理培訓(xùn) EventPublisher

大數(shù)據(jù)培訓(xùn),云培訓(xùn),數(shù)據(jù)挖掘培訓(xùn),云計算培訓(xùn),高端軟件開發(fā)培訓(xùn),項目經(jīng)理培訓(xùn)

  1 using System.Collections.Generic;  2 using Nop.Core.Infrastructure;  3   4 namespace Nop.Services.Events  5 {  6     /// <summary>  7     /// 事件訂閱服務(wù)  8     /// </summary>  9     public class SubscriptionService : ISubscriptionService 10     { 11         /// <summary> 12         /// 獲取事件訂閱 13         /// </summary> 14         /// <typeparam name="T">Type</typeparam> 15         /// <returns>Event consumers</returns> 16         public IList<IConsumer<T>> GetSubscriptions<T>() 17         { 18             return EngineContext.Current.ResolveAll<IConsumer<T>>(); 19         } 20     } 21 } 22

大數(shù)據(jù)培訓(xùn),云培訓(xùn),數(shù)據(jù)挖掘培訓(xùn),云計算培訓(xùn),高端軟件開發(fā)培訓(xùn),項目經(jīng)理培訓(xùn)

二.消費者IConsermer<T>注冊

應(yīng)用啟動時Nop.Web.Framework.DependencyRegistrar中將所有實現(xiàn)IConsumer<T>接口的類注冊到ioc容器中。

通過EngineContext.Current.ResolveAll<IConsumer<T>>(),就可以獲取到某個消息(T)的訂閱了。

大數(shù)據(jù)培訓(xùn),云培訓(xùn),數(shù)據(jù)挖掘培訓(xùn),云計算培訓(xùn),高端軟件開發(fā)培訓(xùn),項目經(jīng)理培訓(xùn)

  1  //注冊事件消費者  2             var consumers = typeFinder.FindClassesOfType(typeof(IConsumer<>)).ToList();  3             foreach (var consumer in consumers)  4             {  5                 builder.RegisterType(consumer)  6                     .As(consumer.FindInterfaces((type, criteria) =>  7                     {  8                         var isMatch = type.IsGenericType && ((Type)criteria).IsAssignableFrom(type.GetGenericTypeDefinition());  9                         return isMatch; 10                     }, typeof(IConsumer<>))) 11                     .InstancePerLifetimeScope(); 12             }

大數(shù)據(jù)培訓(xùn),云培訓(xùn),數(shù)據(jù)挖掘培訓(xùn),云計算培訓(xùn),高端軟件開發(fā)培訓(xùn),項目經(jīng)理培訓(xùn)

三.創(chuàng)建消費者

結(jié)合上邊提到的應(yīng)用場景,我們創(chuàng)建訂閱OrderPaidEvent事件來處理短信通知的消費者。

創(chuàng)建OrderPaidSMSEventConsumer類

大數(shù)據(jù)培訓(xùn),云培訓(xùn),數(shù)據(jù)挖掘培訓(xùn),云計算培訓(xùn),高端軟件開發(fā)培訓(xùn),項目經(jīng)理培訓(xùn)

  1 using System;  2 using Nop.Core;  3 using Nop.Core.Domain.Orders;  4 using Nop.Core.Plugins;  5 using Nop.Services.Events;  6 using Nop.Services.Orders;  7   8 namespace Nop.Plugin.SMS  9 { 10     public class OrderPaidSMSEventConsumer : IConsumer<OrderPaidEvent> 11     { 12  13         private readonly IOrderService _orderService; 14  15         public OrderPaidSMSEventConsumer( 16             IOrderService orderService, 17             IStoreContext storeContext) 18         { 19             this._orderService = orderService; 20             this._storeContext = storeContext; 21         } 22  23         /// <summary> 24         /// 事件處理. 25         /// </summary> 26         /// <param name="eventMessage">The event message.</param> 27         public void HandleEvent(OrderPaidEvent  eventMessage) 28         { 29  30             var order = eventMessage.Order;//獲取訂單 31  32             //發(fā)送短息通知代碼 33 	    //.................... 34         } 35     } 36 }

大數(shù)據(jù)培訓(xùn),云培訓(xùn),數(shù)據(jù)挖掘培訓(xùn),云計算培訓(xùn),高端軟件開發(fā)培訓(xùn),項目經(jīng)理培訓(xùn)

OrderPaidSMSEventConsumer類繼承 IConsumer<OrderPaidEvent>,OrderPaidEvent就是事件類,維護生產(chǎn)者與消費者之間的訂閱關(guān)系。事件類名稱可以自定義,代表了一個事件。

  

接下來我們再創(chuàng)建一個郵件處理的消費者OrderPaidEmailEventConsumer類,同樣繼承了ICnsumer<OrderPaidEvent>,說明我們訂閱的是也是OrderPaidEvent事件。

大數(shù)據(jù)培訓(xùn),云培訓(xùn),數(shù)據(jù)挖掘培訓(xùn),云計算培訓(xùn),高端軟件開發(fā)培訓(xùn),項目經(jīng)理培訓(xùn)

  1 using System;  2 using Nop.Core;  3 using Nop.Core.Domain.Orders;  4 using Nop.Core.Plugins;  5 using Nop.Services.Events;  6 using Nop.Services.Orders;  7   8 namespace Nop.Plugin.Email  9 { 10     public class OrderPaidEmailEventConsumer : IConsumer<OrderPaidEvent> 11     { 12  13         private readonly IOrderService _orderService; 14         private readonly IStoreContext _storeContext; 15  16         public OrderPaidEmailEventConsumer( 17             IOrderService orderService, 18             IStoreContext storeContext) 19         { 20  21             this._orderService = orderService; 22             this._storeContext = storeContext; 23         } 24  25         /// <summary> 26         /// 郵件處理 27         /// </summary> 28         /// <param name="eventMessage">The event message.</param> 29         public void HandleEvent(OrderPaidEvent eventMessage) 30         { 31  32  33             var order = eventMessage.Order; 34  35             //發(fā)送郵件通知客戶 36 	    //............................ 37         } 38     } 39 }

大數(shù)據(jù)培訓(xùn),云培訓(xùn),數(shù)據(jù)挖掘培訓(xùn),云計算培訓(xùn),高端軟件開發(fā)培訓(xùn),項目經(jīng)理培訓(xùn)

四.生產(chǎn)消息

我們已經(jīng)創(chuàng)建了兩個訂閱了OrderPaidEvent事件的消費者,現(xiàn)在我們看看當(dāng)客戶支付完成時我們是如何通知消費者的。

Nop.Services.OrderProcessingService類中

_eventPublisher.Publish(new OrderPaidEvent(order))方法發(fā)送了OrderPaidEvent事件。這時候上邊訂閱OrderPaidEvent事件的消費(短信、郵件)就會處理消息了。

大數(shù)據(jù)培訓(xùn),云培訓(xùn),數(shù)據(jù)挖掘培訓(xùn),云計算培訓(xùn),高端軟件開發(fā)培訓(xùn),項目經(jīng)理培訓(xùn)

五.nop中常用的事件整理

消費者,主要還是處理緩存

Nop.Web.Infrastructure.Cache.ModelCacheEventConsumer:前臺模型相關(guān)

Nop.Admin.Infrastructure.Cache.ModelCacheEventConsumer:后臺模型相關(guān)

Nop.Services.Discounts.Cache.DiscountEventConsumer:折扣相關(guān)

Nop.Services.Catalog.Cache.PriceCacheEventConsumer:價格相關(guān)

Nop.Services.Customers.Cache.CustomerCacheEventConsumer:密碼修改

生產(chǎn)者,下圖總結(jié)了nop 3.9 源碼中自帶的事件及所在的類,大部分是未實現(xiàn)對應(yīng)的消費者。

nop只是在相關(guān)的地方留下事件位置,方便我們二次開發(fā)的時候進行擴展。

大數(shù)據(jù)培訓(xùn),云培訓(xùn),數(shù)據(jù)挖掘培訓(xùn),云計算培訓(xùn),高端軟件開發(fā)培訓(xùn),項目經(jīng)理培訓(xùn)

六.總結(jié)

1.生產(chǎn)者需要繼承IEventPublisher接口。

2.消費者需要繼承IConsumer<T>接口。

3.消費者通過事件類訂閱到生產(chǎn)者,訂閱實現(xiàn)參見ISubscriptionService接口。

nop事件機制實現(xiàn)很簡單,有興趣的朋友可以用RabbitMQ進行消息的擴展。

文中有錯誤的理解和不正確的觀點,請留言,一起交流共同進步。

本文地址:http://www.cnblogs.com/yaoshangjin/p/7234522.html

本文為大波浪原創(chuàng)、轉(zhuǎn)載請注明出處。

如果您認(rèn)為這篇文章還不錯或者有所收獲,可以點擊下方的【關(guān)注】按鈕,因為你的支持是我繼續(xù)寫作,分享的最大動力!

作者:大波浪

來源:http://www.cnblogs.com/yaoshangjin/

聲明: 本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。如果您發(fā)現(xiàn)博客中出現(xiàn)了錯誤,或者有更好的建議、想法,請及時與我聯(lián)系??!如果想找我私下交流,可以私信或者加我QQ。

http://www.cnblogs.com/yaoshangjin/p/7234522.html