簡體   English   中英

如何使用具有不同構造函數參數的接口實現的抽象工廠?

[英]How to use an abstract factory with realizations of an interface that have different constructor parameters?

一切正常,直到實現的構造函數相同。 但是,當構造函數不同時,我有一種進退兩難的境地。 沒問題還是可能存在架構問題? 這是代碼:

public class CategoryViewFactory : ICategoryViewFactory
{
    private readonly ActiveProgressions _activeProgressions;

    public CategoryViewFactory(ActiveProgressions activeProgressions)
    {
        _activeProgressions = activeProgressions;
    }

    public ICategoryView? Create(CategoryType type, Category category)
    {
        return type switch
        {
            CategoryType.Category => new CategoryView(category),
            CategoryType.Subcategory => new SubcategoryView(category, _activeProgressions),
            _ => null
        };
    }
}

ActiveProgression是我使用容器注入的 singleton 服務。 可以嗎? 例如,如果ActiveProgression是一個臨時服務,我應該怎么做? 在這種情況下如何創建SubcategoryView

Create()中放置額外參數的想法似乎很糟糕,但它似乎也是這種情況下唯一的解決方案。

CategoryViewFactoryCreate方法充當 Composer。 Composer 是應用程序的Composition Root的一部分,負責組合實例。 在這種情況下, Create方法使用的是純 DI ,而可以將該職責轉移到 DI 容器。

只要在應用程序的啟動路徑中定義了CategoryViewFactory ,也就是 Composition Root,您所做的一切就都很好。 ActiveProgression甚至可以回調 DI 容器,*只要ActiveProgression也是 Composition Root 的一部分。 ActiveProgression在組合根的上下文之外定義時,它對 DI 容器的使用可以被視為服務定位器,這是一個眾所周知的反模式

例如,如果 ActiveProgression 是一個臨時服務,我應該怎么做?

只要CategoryViewFactory也是瞬態的,就不會有問題。 但是,當CategoryViewFactory為 singleton 時, ActiveProgression將成為Captive Dependency

盡管您所做的一切都很好,但CategoryViewFactory使用 Pure DI 可能不太明顯,而 Composition root 的其他部分使用 DI Container。 您可以考慮CategoryViewFactory將組合的責任轉發給 DI 容器。 例如:

public class CategoryViewFactory : ICategoryViewFactory
{
    private readonly MyDiContainer container;

    public CategoryViewFactory(MyDiContainer container)
    {
        this.container = container;
    }

    public ICategoryView? Create(CategoryType type, Category category)
    {
        var view = this.CreateInternal(type);
        view?.Initialize(category);
        return view;
    }

    private ICategoryView? CreateInternal(CategoryType type)
    {
        return type switch
        {
            CategoryType.Category => container.GetService<CategoryView>(),
            CategoryType.Subcategory => container.GetService<SubcategoryView>(),
            _ => null
        };
    }
}

注意在這種情況下, Category運行時數據不再提供給創建的視圖的構造函數。 這簡化了那些對象的創建,因為它們的構造不再依賴於運行時數據的存在,這是一個很好的做法 這還需要更改您的ICategoryView

暫無
暫無

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

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