[英]Where are concrete class injected in constructor being registered with DI framework?
我試圖了解依賴注入,通常所有東西都是通過構造函數或屬性注入注入的。
到目前為止,我了解到它基本上圍繞模擬 class 的接口。
我正在檢查 Nop Commerce,在那里我遇到了CustomerModelFactory
,它接受幾個域 class,如CustomerSettings
、 DatetimeSettings
等。
現在,當我檢查DependencyRegistrar.cs
class 時,我看不到依賴項注冊如何,甚至在同一個 class 中,我看不到在任何地方創建的CustomerSettings
的新實例。
所以我的問題是,當我們在 class 的構造函數中注入具體的 class 時,我們在哪里注冊它或 IOC 容器如何提供實例?
客戶模型工廠.cs
public partial class CustomerModelFactory : ICustomerModelFactory
{
// all below are concrete class
public CustomerModelFactory(AddressSettings addressSettings,
CaptchaSettings captchaSettings,
CatalogSettings catalogSettings,
CommonSettings commonSettings,
CustomerSettings customerSettings,
DateTimeSettings dateTimeSettings,
}
依賴注冊器.cs
public class DependencyRegistrar : IDependencyRegistrar
{
public virtual void Register(ContainerBuilder builder, ITypeFinder typeFinder, NopConfig config)
{
builder.RegisterType<CustomerModelFactory>().As<ICustomerModelFactory>().InstancePerLifetimeScope();
}
}
我找不到以下完成的位置:
CustomerSettings settings = new CustomerSettings();
or
CatalogSettings settings = new CatalogSettings();
我如何理解這是如何工作的?
這就是為什么 DI 並沒有真正降低復雜性,而是將復雜性隱藏在表面之下,並將生命周期管理轉移到您不太了解的另一件事上,因為每個 DI 框架都是不同的。 無論如何,這是另一個話題。
這里是回答你的問題,忽略哪個DI框架,只是想一般,有3種方法可以讓你獲得一個object的實例
CustomerSettings settings = new CustomerSettings();
Type t = typeof(CustomerSettings);
CustomerSettings settings = Activator.CreateInstance(t) as CustomerSettings;
可能是這樣的:
Dictionary<Type, object> lookup;
lookup.Add(typeof(CustomerSettings), new CustomerSettings()):
(這種方式雖然不會生成新實例)。 現在,如果您需要實例,請讓字典將其提供給您
lookup[typeof(CustomerSettings)]
這個動作,在很多 DI 框架中被稱為Resolved
。
為此,許多 DI 框架會使用反射來查找匹配類型。 應該總是有一個過程來注冊您希望 DI 框架自動解析的類型。 這意味着,您告訴 DI 框架它需要知道什么類型,然后在您使用該類型查找時將其返回給我。
例如,您可能會看到如下代碼:
container.Register<CustomerSettings>();
在這種情況下, CustomerSettings
是 class 類型,因此 DI 知道在需要時如何創建它。
但是,如果您正在注冊一個接口
container.Register<ICustomerSettings, CustomerSettings>():
以上是注冊接口及其具體類型的一種語法。 基本上,你告訴 DI,這是類型,這就是實現。 所以當你這樣做時:
var setting = container.Resolve<ICustomerSettings>();
您將獲得CustomerSettings
的一個實例。
如果您有相同接口的多個實現,它將起作用,但您需要一些特殊處理。 不同的DI處理方式不同。
希望到目前為止它有點意義。
每個 DI 框架都有一個 IOC 容器,其作用類似於字典。 您將類型注冊到那里,並要求它返回。
還有更多細節,但我不會在這里介紹。
MS.DI 不會自動解析具體類型; 他們需要明確注冊。 因此,NopCommerce 在其DependencyRegistrar
class 中注冊它們(第241行):
//register all settings
var settings = typeFinder.FindClassesOfType(typeof(ISettings), false).ToList();
foreach (var setting in settings)
{
services.AddScoped(setting, serviceProvider =>
{
var storeId = DataSettingsManager.IsDatabaseInstalled()
? serviceProvider.GetRequiredService<IStoreContext>()
.GetCurrentStoreAsync().Result?.Id ?? 0
: 0;
return serviceProvider.GetRequiredService<ISettingService>()
.LoadSettingAsync(setting, storeId).Result;
});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.