![](/img/trans.png)
[英]How to create a generic factory returning different interface types and an abstract class
[英]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()
中放置額外參數的想法似乎很糟糕,但它似乎也是這種情況下唯一的解決方案。
CategoryViewFactory
的Create
方法充當 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.