繁体   English   中英

在构造函数中注入的具体 class 在哪里注册到 DI 框架?

[英]Where are concrete class injected in constructor being registered with DI framework?

我试图了解依赖注入,通常所有东西都是通过构造函数或属性注入注入的。

到目前为止,我了解到它基本上围绕模拟 class 的接口。

我正在检查 Nop Commerce,在那里我遇到了CustomerModelFactory ,它接受几个域 class,如CustomerSettingsDatetimeSettings等。

现在,当我检查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的实例

  1. 需要时直接创建实例
CustomerSettings settings = new CustomerSettings();
  1. 需要时通过反射创建实例
Type t = typeof(CustomerSettings);
CustomerSettings settings = Activator.CreateInstance(t) as CustomerSettings;
  1. 缓存字典中的所有实例,并在使用类型名称时查找

可能是这样的:

Dictionary<Type, object> lookup;
lookup.Add(typeof(CustomerSettings), new CustomerSettings()): 

(这种方式虽然不会生成新实例)。 现在,如果您需要实例,请让字典将其提供给您

lookup[typeof(CustomerSettings)]

这个动作,在很多 DI 框架中被称为Resolved


DI 框架是如何找到它的呢?

为此,许多 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM