2016-11-03 35 views
1

這是一個初學者關於使用工作單元,存儲庫和簡單注入器服務來持久化數據的問題。如果存儲庫要求IUnitOfWorkAsync並且服務要求Repository<>,您將如何從服務層或調用它的Controller層調用UnitOfWork.Save()?使用Simple Injector進行依賴注入,你如何引用一個Unit Of Work對象來保存數據?

我知道我可以創建一個Singleton工作單元,然後請求參考服務級別的工作單元,但我不想這樣做,因爲不同的控制器需要以不同方式保存數據。 (我也試過讓在服務IUnitOfWorkAsync參考,但它是一個不同的對象,並調用SaveChanges沒有效果

我已經註冊這些與簡單的注射器:

container.Register<IUnitOfWorkAsync, UnitOfWork>(Lifestyle.Scoped); 
container.Register(typeof(IRepositoryAsync<>), typeof(Repository<>)); 
container.Register(typeof(IHelpService), typeof(HelpService)); 

這是我的倉庫,我的服務:

// For each repository like CustomerRepository, OrderRepository 
// additional comma separated parameters to the HelpService as necessary 
public Repository(IDataContextAsync context, IUnitOfWorkAsync uow) 

public HelpService(IRepositoryAsync<HelpTopics> repository) : base(repository) { } 

回答

1

如果存儲庫要求一個IUnitOfWorkAsync和服務要求對儲存<>,你怎麼會無論從SERVICE L本叫UnitOfWork.Save()? ayer或稱爲它的Controller層?

你不想讓控制器調用Save,因爲這不是他們的責任。您也不希望這些服務調用Save方法,因爲這會導致代碼重複並且很容易忘記調用Save

解決方案是讓服務和控制器都不可見的中間層,它允許您保存工作單元,而且應該沒有代碼重複。

實現此目的的一種方法是相應地調整您的應用程序設計。我找到的最有效的設計是this one,其中每個用例都在系統中獲取自己的消息,並且將這種用例的業務邏輯封裝在實現通用接口的單個​​類中。

該設計允許創建可以包裝每個業務操作的裝飾器,並在操作成功完成時調用UnitOfWork.Save()

同樣,答案在於this design

+0

您的答案意味着UOW應該提供與其相關的存儲庫的引用,而不是提到單個UOW的多個存儲庫?我認爲這意味着服務定位器可以在UOW中爲Handlers提供替代方案來創建回購實例。 [鏈接](http://simpleinjector.readthedocs.io/en/latest/howto.html#resolve-instances-by-key)是類似的思維還是我完全錯過了?我錯過的部分是你的'MoveCustomerCommandHandler'如何引用存儲庫(假設最終的一致性?) –

+1

@ Dr.Zim:你可以用這兩種方式,而且沒有一個是壞的。無論哪種方式,這並不意味着服務定位器*。如果你的UoW只不過是一系列的Repostories,你的UoW實現可以位於[Composition Root](http://blog.ploeh.dk/2011/07/28/CompositionRoot/)中。這種方式實現可以直接取決於Container。組合根中的容器的使用是[不實施服務定位器反模式](http://blog.ploeh.dk/2011/08/25/ServiceLocatorrolesvs.mechanics/)。 – Steven

+0

「MoveCustomerCommandHandler」可以依賴於UoW或特定的存儲庫。無論您是否使用最終一致性都與此無關。 – Steven

相關問題