[英]How to use Simple injector for repository in business layer
我希望在我的MVC層中根本沒有存儲庫。
我在DAL項目層中具有通用的EFRepository
, IRepository
和PASContext
(從DbContext繼承)。
我已經在我的MVC項目下以快速入門安裝了Simple Injector,這可以讓我進入每個控制器的構造函數中我想要的存儲庫。
但是在我的解決方案中,我也有BLL項目,並且我希望MVC層僅與BLL層通信,因為這是項目體系結構,將來我想在BLL層的類中添加邏輯。
我也不想在我的BLL層中創建上下文,但是存儲庫沒有帶0參數的構造函數,這是我的ProductBLL
類:
public class BLLProducts
{
IRepository<Product> ProductRepository;
public BLLProducts(EFRepository<Product> Repository)
{
ProductRepository = Repository;
}
public ICollection<Product> getAll()
{
return ProductRepository.All().ToList();
}
}
如何在不創建存儲庫/上下文的情況下從控制器或從unitTest初始化BLLProduct
類? 這樣我就可以在這里保留我的抽象了。
我知道我需要在這里使用簡單注入器,我只是不知道如何使用。
從控制器的角度來看,只需將BLLProducts
注入其中即可,如下所示:
// constructor
public HomeController(BLLProducts products) {
this.products = products;
}
從單元測試的角度來看,讓控制器依賴於具體的類是次優的(這違反了Dependency Inversion Principle )。 這是次優的,因為你現在需要創建一個BLLProducts
實例,並用它實例DbContext
,但這種的DbContext是特定於實體框架,它依賴一個數據庫。 這使測試變得越來越困難。 您希望單元測試在沒有數據庫的情況下運行。
因此,解決方案是將此BLLProducts
類隱藏在抽象后面。 一種簡單的方法是從此類中提取接口:
public interface IBLLProducts {
ICollection<Product> getAll();
}
這使得對控制器進行單元測試變得更加容易。 您要做的唯一一件事就是讓它依賴於此新接口:
public HomeController(IBLLProducts products) {
this.products = products;
}
您將需要在Simple Injector中注冊此IBLLProducts
接口:
container.Register<IBBLProducts, BLLProducts>();
整個模型仍然有一些缺點。 例如,盡管Simple Injector可以為您創建和處置DbContext,但您在哪里調用SubmitChanges? 在網絡請求結束時執行此操作是一個壞主意。 我為此找到的唯一方便的解決方案是遷移到更堅固的體系結構。 例如,看看這個問題 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.