簡體   English   中英

如何將簡單注入器用於業務層中的存儲庫

[英]How to use Simple injector for repository in business layer

我希望在我的MVC層中根本沒有存儲庫。

我在DAL項目層中具有通用的EFRepositoryIRepositoryPASContext (從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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM