简体   繁体   English

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

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

I am trying to understand Dependency Injection where usually everything is injected as either via Constructor or Property Injection.我试图了解依赖注入,通常所有东西都是通过构造函数或属性注入注入的。

So far I have understood that it basically revolves around interface to mock the class.到目前为止,我了解到它基本上围绕模拟 class 的接口。

I am checking out Nop Commerce where I came across CustomerModelFactory which accepts couple of Domain class like CustomerSettings , DatetimeSettings etc..我正在检查 Nop Commerce,在那里我遇到了CustomerModelFactory ,它接受几个域 class,如CustomerSettingsDatetimeSettings等。

Now when I check the DependencyRegistrar.cs class, I don't see how the dependency registration or even in the same class, I don't see the new instance of CustomerSettings created anywhere.现在,当我检查DependencyRegistrar.cs class 时,我看不到依赖项注册如何,甚至在同一个 class 中,我看不到在任何地方创建的CustomerSettings的新实例。

So my question is when we inject concrete class in constructor of class, where do we register it or how IOC container supply the instance?所以我的问题是,当我们在 class 的构造函数中注入具体的 class 时,我们在哪里注册它或 IOC 容器如何提供实例?

CustomerModelFactory.cs客户模型工厂.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,
    }

DependencyRegistrar.cs依赖注册器.cs

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

I couldn't find where below is done:我找不到以下完成的位置:

CustomerSettings settings = new CustomerSettings();
    or
CatalogSettings settings = new CatalogSettings();

How can I understand how this is working?我如何理解这是如何工作的?

That's why DI does not really reduce complexity, instead, it hides complexity under surface and offload lifecycle management to another thing that you don't really know too much, as each DI framework is different.这就是为什么 DI 并没有真正降低复杂性,而是将复杂性隐藏在表面之下,并将生命周期管理转移到您不太了解的另一件事上,因为每个 DI 框架都是不同的。 Anyway, that is another topic.无论如何,这是另一个话题。

Here is to answer your question, ignore which DI framework, just think in general, there are 3 ways for you to get an instance of an object这里是回答你的问题,忽略哪个DI框架,只是想一般,有3种方法可以让你获得一个object的实例

  1. Create the instance directly when you need it需要时直接创建实例
CustomerSettings settings = new CustomerSettings();
  1. Create the instance by Reflection when you need it需要时通过反射创建实例
Type t = typeof(CustomerSettings);
CustomerSettings settings = Activator.CreateInstance(t) as CustomerSettings;
  1. Cache all instances in a dictionary and look up when using the type name缓存字典中的所有实例,并在使用类型名称时查找

something can be like this:可能是这样的:

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

(This way does not generate a new instance though). (这种方式虽然不会生成新实例)。 Now if you need the instance, you ask the dictionary to give it to you现在,如果您需要实例,请让字典将其提供给您

lookup[typeof(CustomerSettings)]

This action, is called Resolved in many DI framework.这个动作,在很多 DI 框架中被称为Resolved


How does the DI framework find it though? DI 框架是如何找到它的呢?

To do this, many DI framework will use reflection to find the matching type.为此,许多 DI 框架会使用反射来查找匹配类型。 There should always a process to register the types you want DI framework to resolve automatically.应该总是有一个过程来注册您希望 DI 框架自动解析的类型。 It means, you tell DI framework what type it needs to be aware, and then give it back to me when you look up using the type.这意味着,您告诉 DI 框架它需要知道什么类型,然后在您使用该类型查找时将其返回给我。

For example, you may see code like this:例如,您可能会看到如下代码:

container.Register<CustomerSettings>(); 

In this case, CustomerSettings is a class type, so DI knows how to create it when you need it.在这种情况下, CustomerSettings是 class 类型,因此 DI 知道在需要时如何创建它。

However, if you are registering an interface但是,如果您正在注册一个接口

container.Register<ICustomerSettings, CustomerSettings>(): 

The above is one syntax to register interface and its concrete type.以上是注册接口及其具体类型的一种语法。 Basically, you tell DI, this is the type, and that is the implementation.基本上,你告诉 DI,这是类型,这就是实现。 So when you do this:所以当你这样做时:

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

You will get an instance of CustomerSettings .您将获得CustomerSettings的一个实例。

It will work if you have multiple implementations of the same interface, but you need some special handling.如果您有相同接口的多个实现,它将起作用,但您需要一些特殊处理。 Different DI handles it differently.不同的DI处理方式不同。

Hopefully so far it makes a little sense.希望到目前为止它有点意义。

Each DI framework has an IOC container, which acts like a dictionary.每个 DI 框架都有一个 IOC 容器,其作用类似于字典。 You register the type into there, and ask it to give it back.您将类型注册到那里,并要求它返回。

There are more details, but I will not cover in here.还有更多细节,但我不会在这里介绍。

Concrete types are not automatically resolved by MS.DI; MS.DI 不会自动解析具体类型; they need to be registered explicitly.他们需要明确注册。 NopCommerce, therefore, registers them inside its DependencyRegistrar class (on line 241 ):因此,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.

相关问题 Unity DI注册实例未正确注入 - Unity DI Registered Instances not injected correctly 具有内部构造函数的Moq混凝土类 - Moq Concrete Class with Internal Constructor 正在注入的构造函数注入和初始化依赖项 - Constructor injection and initialization of dependencies being injected Prism / Unity使用新的具体类更新已解析/已注入的引用 - Prism / Unity update resolved/injected references with new concrete class 如何在从基础 class 继承的 class 中编写 class 构造函数,其中基础 ZA2F2ED4F8EBC2CBB4C21AAB29DC4 需要注入服务? - How can I code a class constructor in a class that inherits from a base class where the base class needs a service injected? 通用实现,但构造函数参数取决于具体类 - Generic implementation, but constructor arguments depend on concrete class 如何用依赖注入的构造函数注册一个类? (简单) - How to register a class with a dependency injected constructor? (SimpleIoC) 在C#中使用注入的构造函数实例化一个类 - Instantiating a class with injected constructor in C# 实体框架中的继承-每个具体类的表? - Inheritance in entity framework - Table per concrete class? 为什么将长度为0的byte []注入我的班级? - Why is a byte[] of 0 Length being injected into my class?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM