[英]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.