日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用领域事件

發布時間:2023/12/4 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用领域事件 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.引言

最近剛學習了下DDD中領域事件的理論知識,總的來說領域事件主要有兩個作用,一是解耦,二是使用領域事件進行事務的拆分,通過引入事件存儲,來實現數據的最終一致性。若想了解DDD中領域事件的概念,可參考DDD理論學習系列(9)-- 領域事件。

Abp中使用事件總線來實現領域事件,而關于事件總線的實現,大家可參考我這篇博文——事件總線知多少,本文將不再贅述。

2.用例分析

當用戶被成功分配任務后,發送郵件和消息通知給用戶。

這個用例比較簡單,沒有太多的復雜邏輯,按照我們傳統的思路,直接在任務編輯方法中添加郵件和消息發送的方法即可,代碼如下:

public void UpdateTask(UpdateTaskInput input){ ?
?//We can use Logger, it's defined in ApplicationService base class.Logger.Info("Updating a task for input: " + input); ? ?
?//獲取是否有權限bool canAssignTaskToOther = PermissionChecker.IsGranted(PermissionNames.Pages_Tasks_AssignPerson); ?
? ?//如果任務已經分配且未分配給自己,且不具有分配任務權限,則拋出異常if (input.AssignedPersonId.HasValue && input.AssignedPersonId.Value != AbpSession.GetUserId() &&!canAssignTaskToOther){ ? ? ? ?throw new AbpAuthorizationException("沒有分配任務給他人的權限!");} ? ?var updateTask = Mapper.Map<Task>(input); ? ?var user = _userRepository.Get(input.AssignedPersonId.Value); ? ?//先執行分配任務_taskManager.AssignTaskToPerson(updateTask, user); ? ?//再更新其他字段_taskRepository.Update(updateTask); ? ?//發送通知var message = "You hava been assigned one task into your todo list.";_smtpEmailSender.Send("ysjshengjie@qq.com", updateTask.AssignedPerson.EmailAddress, "New Todo item", message);_notificationPublisher.Publish("NewTask", new MessageNotificationData(message), null,NotificationSeverity.Info, new[] { updateTask.AssignedPerson.ToUserIdentifier() }); }

運行,直接掛掉。原因是很清楚,是由于郵箱配置有誤導致。但是我們思考一下。我們進行任務分配時最關注的是任務被成功分配,而至于通知是否成功發送相對來說是次要的。但是現在卻由于通知發送失敗導致任務無非被成功分配,這是不合理的。

那我們要如何做呢?當然是拆分業務邏輯。而這時領域事件就可以粉墨登場了。

3.使用領域事件

就這個用例而言,“用戶被成功分配任務”就是一個領域事件。下面我們就來實際應用一下。

3.1. 定義事件源

一個領域事件是通過事件源來識別的,我們直接定義一個TaskAssignedEventData繼承自EventData即可:

public class TaskAssignedEventData : EventData{ ?

? ?public User User { get; set; } ?
???public Task Task { get; set; } ?
??
?? ?public TaskAssignedEventData(Task task, User user) ? ?{ ?
?? ? ? ? ?this.Task = task; ? ?
?? ? ? ? ?this.User = user;} }

3.2. 實現事件處理

定義TaskAssignedToUser事件處理,實現IEventHandler<TaskAssignedEventData>泛型接口即可:

public class TaskAssignedToUser : IEventHandler<TaskAssignedEventData>, ITransientDependency { ?
? ?private readonly ISmtpEmailSender _smtpEmailSender; ?
? ?private readonly INotificationPublisher _notificationPublisher;

? ????public TaskAssignedToUser(ISmtpEmailSender smtpEmailSender, INotificationPublisher notificationPublisher) ? ?{_smtpEmailSender = smtpEmailSender;_notificationPublisher = notificationPublisher;} ? ?public void HandleEvent(TaskAssignedEventData eventData) ? ?{var message = "You hava been assigned one task into your todo list."; ? ? ? ?//TODO:需要重新配置QQ郵箱密碼_smtpEmailSender.Send("ysjshengjie@qq.com", eventData.Task.AssignedPerson.EmailAddress, "New Todo item", message);_notificationPublisher.Publish("NewTask", new MessageNotificationData(message), null,NotificationSeverity.Info, new[] { eventData.User.ToUserIdentifier() });} }

3.3. 事件觸發

我們可以直接在上一節定義的TaskManager領域服務中觸發領域事件。因為這樣更符合當前領域事件通用語言的表述。

//TaskManager.cspublic void AssignTaskToPerson(Task task, User user){ ?
?//已經分配,就不再分配if (task.AssignedPersonId.HasValue && task.AssignedPersonId.Value == user.Id){ ? ? ?
? ?return;} ?
??if (task.State != TaskState.Open){ ? ? ?
???throw new ApplicationException("處于非活動狀態的任務不能分配!");}task.AssignedPersonId = user.Id; ? ?//使用領域事件觸發發送通知操作_eventBus.Trigger(new TaskAssignedEventData(task, user)); }

再運行,我們發現雖然沒有接收到消息通知(發送失敗),但任務卻可以成功分配。

4. 一些問題

  • 領域事件在哪注冊(訂閱)?
    應用程序啟動時Abp根據約定俗成的命名規則將事件源和事件處理注冊到了依賴容器中和事件總線維護的容器中。我們也可以自行在應用服務或領域服務中手動注冊。

  • 領域事件在哪觸發(發布)?
    事件的觸發同樣也沒有限定,根據需要,可以在應用服務、領域服務、聚合、實體中發布。

  • 領域事件的命名?
    領域事件的名字要反映出過去發生的事情的概念。

  • 4.最后

    由于demo比較簡單,找不到合適的用例,以上使用的用例比較簡單。在復雜的用例中,當需要更新多個聚合時,領域事件的作用就體現出來了,借助領域事件我們可以很好的進行事務拆分,達到最終一致性的目的。

    而至于領域事件衍生出來的事件存儲和事件溯源,下次再和大家分享。

    相關文章

    • DDD理論學習系列(1)-- 通用語言

    • DDD領域驅動之干貨 (一)

    • DDD理論學習系列(2)-- 領域

    • DDD理論學習系列(3)-- 限界上下文

    • DDD理論學習系列(4)-- 領域模型

    • 事件總線知多少(2)

    • DDD理論學習系列(5)-- 統一建模語言

    • DDD理論學習系列(6)-- 實體

    • DDD理論學習系列(7)-- 值對象

    • DDD理論學習系列(8)-- 應用服務&領域服務

    • DDD理論學習系列(9)-- 領域事件

    • 從事件和DDD入手來構建微服務

    • DDD領域驅動之干貨 (一)

    • WeText項目:一個基于.NET實現的DDD、CQRS與微服務架構的演示案例

    • 【DDD/CQRS/微服務架構案例】在Ubuntu 14.04.4 LTS中運行WeText項目的服務端

    原文地址:http://www.cnblogs.com/sheng-jie/p/7136279.html


    .NET社區新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注

    總結

    以上是生活随笔為你收集整理的使用领域事件的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。