0

關於域基礎設施是確定把它們想象成:DDD領域專用/通用基礎設施

  • 一般:如何發送電子郵件/讀取配置文件,等等。
  • 具體:如何發送激活碼給新用戶(域實體)

在哪裏,如果我想依賴:

  • <參考>一般基礎設施(用於記錄,一般例外,等..)

  • 特定的基礎設施 <參考>一般基礎設施&域(獲得基礎設施相關的操作接口,如IActivationCodeSender並能夠實現EmailActivationCodeSender &和SmsActivationCodeSender

在這種情況下,我的應用層負責將所需激活方法傳遞(DI解決)我的域實體,我們可以說:

User.Register(IActivationCodeSender activationCodeSender) 
{ 
    // Register user and generate activation code 1234 
    ... 
    activationCodeSender.Send(this, "1234"); 
} 

這是壞?我應該在我的(一般)基礎設施上工作,確保它支持以統一的方式發送短信/電子郵件(恐怕這種情況可能會給我的通用基礎設施帶來複雜性)並刪除此類特定基礎設施層將混合業務邏輯與基礎設施相關的操作?所以相反,我會使用以下內容:

INotificationSender的兩個(一般)實現;一個EmailNotificationSenderSmsNotificationSender

User.Register(INotificationSender activationCodeSender) 
{ 
    // Register user and generate activation code 1234 
    ... 
    // this.NotificationAddressInfo includes email address and mobile phone # 

    activationCodeSender.Send(new Notification(this.NotificationAddressInfo, "Your activation code is 1234")); 
} 

回答

0

我會建議用戶一旦註冊,無法創建訂閱。並將您的代碼生成和通知邏輯放入訂閱聚合器中。它將控制需要發送什麼以及序列是什麼。如果失敗,該怎麼辦等等。而且你的通知可能是基礎設施的一部分,因爲它對你的域名一無所知。只需收到電子郵件併發送出去。

0

沒有域基礎結構。
你的客戶不關心你將如何發送電子郵件。

+0

因此,您認爲基礎架構項目不應該引用域項目,而應該獨立於任何域(無域基礎架構)工作? – user997923

1

我建議你考慮使用具有這些基本原則(維基百科)的Dependency inversion principle

  1. 高層模塊不應該依賴於低級別的模塊。 都應該依賴於抽象。
  2. 根據細節,抽象不應取決於 。細節應該取決於抽象。

所以我把喜歡IActivationSender所有接口都在您的域,然後實現在一個單獨的基礎設施項目的這個接口。正如您所提到的,使用DI在應用程序服務(或域服務)中注入所需的實現。

這樣,你直接通過接口的實現爲domain entity你能避免使用Douple dispatch pattern

User.Register(INotificationSender activationCodeSender)

,而是有類似:

UserService.Register(user);

Wh用戶服務可以是注入了正確INotificationSender的域服務。

解決此問題的完全其他方式可能是使用域事件(請參閱Udi Dahans article)。遵循這種模式,您的用戶實體將引發一個「UserCreated」事件,INotificationSender將依次訂閱該事件。通過這種方式,您可以解除從用戶實體發送通知消息的顧慮。