微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决在构造函数中注入的具体类在哪里注册到 DI 框架?

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

到目前为止,我已经理解它基本上围绕着接口来模拟类。

我正在检查 nop Commerce,在那里我遇到了 0x0000000000007b,它接受​​几个域类,如 CustomerModelFactoryCustomerSettings 等。

现在,当我检查 DatetimeSettings 类时,我看不到依赖项是如何注册的,甚至在同一个类中,我也看不到在任何地方创建的 DependencyRegistrar.cs 新实例。>

所以我的问题是,当我们在类的构造函数中注入具体类时,我们在哪里注册它或 IOC 容器如何提供实例?

CustomerModelFactory.cs

CustomerSettings

DependencyRegistrar.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,}

我找不到以下完成的位置:

 public class DependencyRegistrar : IDependencyRegistrar
    {
       
        public virtual void Register(ContainerBuilder builder,ITypeFinder typeFinder,nopConfig config)
        {
          builder.RegisterType<CustomerModelFactory>().As<ICustomerModelFactory>().InstancePerLifetimeScope();
    }
}

我如何理解这是如何工作的?

解决方法

这就是为什么 DI 并没有真正降低复杂性,相反,它将复杂性隐藏在表面之下,并将生命周期管理转移到另一件您不太了解的事情上,因为每个 DI 框架都是不同的。无论如何,这是另一个话题。

这里回答你的问题,忽略是哪个DI框架,大体上想想,有3种方法可以让你获得一个对象的实例

  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 是一个类类型,因此 DI 知道如何在您需要时创建它。

但是,如果您正在注册一个接口

container.Register<ICustomerSettings,CustomerSettings>(): 

以上是注册接口及其具体类型的一种语法。基本上,你告诉 DI,这是类型,那是实现。所以当你这样做时:

var setting = container.Resolve<ICustomerSettings>();

您将获得一个 CustomerSettings 实例。

如果你有同一个接口的多个实现,它会起作用,但你需要一些特殊的处理。不同的 DI 处理方式不同。

希望到目前为止它有点道理。

每个 DI 框架都有一个 IOC 容器,它的作用就像一本字典。您将类型注册到那里,并要求它归还。

还有更多细节,但我不会在这里介绍。

,

具体类型不会被 MS.DI 自动解析;他们需要明确注册。因此,NopCommerce 将它们注册到其 DependencyRegistrar 类中(在线 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;
    });
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。