簡體   English   中英

使用Autofac解決實體框架TPH繼承的依賴關系的設計模式

[英]Design Patterns to resolve dependency using Autofac for Entity Framework TPH inheritance

我已經在實體框架中使用TPH在數據庫中創建庫存表。

public abstract class Inventory
{
    public Guid Id { get; set; }
    public DateTime On { get; set; }
}
public class CycleCountInventory : Inventory
{
    public string Frequency { get; set; }
    // and other properties
}
public class SkuGroupInventory : Inventory
{
    public string SkuGroup { get; set; }
    // and other properties
}

我有一項要求,可以將物品添加到庫存中。 但是,根據庫存類型,庫存回購的行為應有所不同。 我有一個服務類,其中包含對倉庫的引用,如下所示:

public class InventoryService : IInventoryService
{

    public bool AddItems(Inventory inventory, IList<Guid> itemsGuidList)
    {
        // the inventory type is only known at this point

        IInventoryRepo repo = (inventory is SkuGroupInventory)
            ? (IInventoryRepo) new SkuGroupInventoryRepo()
            : new CycleCountInventoryRepo();

        return repo.PerformInventory(itemsGuidList);
    }

}

目前,我正在通過手動執行檢查來加載IInventoryRepo的不同實現。 這種方法存在一些問題:
1.我已經使用Autofac來解決所有依賴關系...這種方法使我的代碼難以測試
2.隨着添加更多類型的清單,我的代碼將變得難以管理

是否有任何模式(抽象工廠/策略等)可用於委托將依賴項解析回Autofac。 我敢肯定有人會遇到這個問題。 謝謝!

您可以在此處使用工廠模式。

public interface IInventoryFactory 
{
 // instead of type, you could also have a discriminator on the
 // inventory class, to give its specific type. (enum etc.)
 IInventoryRepo CreateInventoryRepo(Type inventoryType);
}

public class MyInventoryFactory : IInventoryFactory 
{
 // instead of type, you could also have a discriminator on the
 // inventory class, to give its specific type. (enum etc.)
 public IInventoryRepo CreateInventoryRepo(Type inventoryType)
 {
   IInventoryRepo repo = (inventoryType == typeof(SkuGroupInventory))
        ? (IInventoryRepo) new SkuGroupInventoryRepo()
        : new CycleCountInventoryRepo();

   return repo;
 }
}

public class InventoryService : IInventoryService
{
    private readonly IInventoryFactory _inventoryFactory;

    public InventoryService(IInventoryFactory inventoryFactory)
    {
     _inventoryFactory = inventoryFactory;
    }

    public bool AddItems(Inventory inventory, IList<Guid> itemsGuidList)
    {
        // create the right repo based on type of inventory.
        // defer it to the factory

        IInventoryRepo repo = _inventoryFactory.CreateInventoryRepo(inventory.GetType());

        return repo.PerformInventory(itemsGuidList);
    }
 }

工廠的實際具體實現將由Autofac注入,因此請在Autofac中進行注冊。 由於可以模擬工廠,因此此Service類方法現在可以進行單元測試。

而且工廠本身可以進行單元測試,因為您只需要傳遞適當的“庫存”實例來聲明正確的具體存儲庫即可。

ps請注意,Autofac甚至不需要工廠接口/混凝土類。 它可以為您注入自動工廠。 但是使用Autofac自動工廠還是使用基於顯式界面的工廠只是人們的偏愛。 無論您喜歡哪個。

同樣,GetType會稍微提高性能。.在生產場景中,如果您的AddItems方法被調用了數千次,則GetType並不是一個很好的FIRST選項。.很多人如下解決它:

  1. 向抽象Inventory類添加一個僅稱為getterType的抽象獲取方法枚舉

  2. 枚舉定義值為CycleCount,SkuGroup等。

  3. 用具體的類型重寫具體子類中的枚舉獲取器。

  4. 一旦發生這種情況,CreateInventoryRepo方法可以將此枚舉作為參數。

 public IInventoryRepo CreateInventoryRepo(InventoryType inventoryType) { IInventoryRepo repo = (inventoryType == InventoryType.SkuGroup) ? (IInventoryRepo) new SkuGroupInventoryRepo() : new CycleCountInventoryRepo(); return repo; } 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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