2014-04-30 78 views
0

我有一個域服務需要應用一些影響基礎設施層的規則,因爲它們是域需求。簡而言之:基礎設施政策&策略。域服務中的基礎設施問題

public MyService : IMyService { 

    private readonly RetryPolicy<ConnectionErrorDetectionStrategy> _retryPolicy; 
    // there might be other strategies for other concerns 
    private readonly IRepository _repository; 

    public MyService(IRepository repository) { 
     _repository = repository; 
     _retryPolicy = new RetryPolicy<ConnectionErrorDetectionStrategy>(); 
    } 

    public Do() { 

     _repository.CrudMagic(); 
     _retryPolicy.ExecuteAction(() => _repository.Commit()); 

    } 

} 

要求是爲了確保在某些情況下(情況),軟件應在應用程序失敗(政策)連接到數據庫進行多次重試(戰略)。然而,這感覺很尷尬,因爲域名不知道連接是什麼(整個DAL甚至可能是模擬!)。我怎樣才能確保正確的策略適用於這種特定的服務/案例?

回答

0

使用代理或裝飾。

class MyService : IMyService {...} 
class MyRetryService: IMSyService { 
    private readonly IMSyService target; //inject MyService 
    private readonly RetryPolicy<ConnectionErrorDetectionStrategy> _retryPolicy; 
} 

當單元測試時將模擬注入目標(IMSyService)。只需期待並驗證目標的調用。如果失敗已經發生並且重試有效,則應該按照指定的策略多次調用目標。

另一種方法是AOP(如果您的平臺上有成熟的框架/ lib)。測試方法是一樣的。

+0

「*應該多次調用目標*」你是怎麼說的? RetryPolicy是一個有狀態的應用程序層服務,它可以自動重複某個動作,例如,拋出異常。如果我將調用目標(IMyService.Do())的次數與策略中指定的次數一樣多,我最終會在數據庫中有x個條目(或者由於實體已存在,甚至會有更多的異常)。 – Acrotygma

+0

此外,從Do()分離所需的操作(commit())並將其放在接口上也是錯誤的,因爲我的服務不允許客戶端提交。提交只是客戶操作的一部分。 – Acrotygma

+0

當出現問題時,RetryPolicy的目標是在預定義的時間重試某些操作嗎?如果一切正常,只執行一次該操作? – Hippoom