Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在DI框架中注册的构造函数中注入的具体类在哪里?_C#_Asp.net Mvc_Dependency Injection_Nopcommerce_Nopcommerce 4.2 - Fatal编程技术网

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

C# 在DI框架中注册的构造函数中注入的具体类在哪里?,c#,asp.net-mvc,dependency-injection,nopcommerce,nopcommerce-4.2,C#,Asp.net Mvc,Dependency Injection,Nopcommerce,Nopcommerce 4.2,我试图理解依赖项注入,通常所有东西都是通过构造函数或属性注入注入的 到目前为止,我了解到它基本上是围绕接口来模拟类的 我正在查看Nop Commerce,在那里我遇到了CustomerModelFactory,它接受两个域类,如CustomerSettings,DatetimeSettings等 现在,当我检查DependencyRegistrar.cs类时,我看不到依赖项注册是如何进行的,甚至在同一个类中,我也看不到在任何地方创建的CustomerSettings的新实例 所以我的问题是,当我

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

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

我正在查看Nop Commerce,在那里我遇到了
CustomerModelFactory
,它接受两个域类,如
CustomerSettings
DatetimeSettings

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

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

CustomerModelFactory.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();
    }
}
DependencyRegister.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种方法可以获得对象的实例

  • 需要时直接创建实例
  • 在需要时通过反射创建实例
  • 缓存字典中的所有实例,并在使用类型名称时查找
  • 可以是这样的:

    Dictionary<Type, object> lookup;
    lookup.Add(typeof(CustomerSettings), new CustomerSettings()): 
    
    container.Register<CustomerSettings>(); 
    
    在本例中,
    CustomerSettings
    是一个类类型,因此DI知道如何在需要时创建它

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

    container.Register<ICustomerSettings, CustomerSettings>(): 
    
    container.Register():
    
    上面是注册接口及其具体类型的语法。基本上,你告诉DI,这就是类型,这就是实现。所以当你这样做的时候:

    var setting = container.Resolve<ICustomerSettings>();
    
    var设置=container.Resolve();
    
    您将获得一个
    CustomerSettings
    的实例

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

    希望到目前为止这有点道理

    每个DI框架都有一个IOC容器,其作用类似于字典。您将类型注册到那里,并要求它将其返回


    这里有更多的细节,但我将不在这里介绍。

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

    这里是为了回答您的问题,忽略哪个DI框架,只需考虑一般情况,有3种方法可以获得对象的实例

  • 需要时直接创建实例
  • 在需要时通过反射创建实例
  • 缓存字典中的所有实例,并在使用类型名称时查找
  • 可以是这样的:

    Dictionary<Type, object> lookup;
    lookup.Add(typeof(CustomerSettings), new CustomerSettings()): 
    
    container.Register<CustomerSettings>(); 
    
    在本例中,
    CustomerSettings
    是一个类类型,因此DI知道如何在需要时创建它

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

    container.Register<ICustomerSettings, CustomerSettings>(): 
    
    container.Register():
    
    上面是注册接口及其具体类型的语法。基本上,你告诉DI,这就是类型,这就是实现。所以当你这样做的时候:

    var setting = container.Resolve<ICustomerSettings>();
    
    var设置=container.Resolve();
    
    您将获得一个
    CustomerSettings
    的实例

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

    希望到目前为止这有点道理

    每个DI框架都有一个IOC容器,其作用类似于字典。您将类型注册到那里,并要求它将其返回


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

    具体类型不是由MS.DI自动解析的;它们需要明确注册。因此,NopCommerce在其
    DependencyRegister
    类(在线)中注册它们:

    //注册所有设置
    var settings=typeFinder.FindClassesOfType(typeof(ISettings),false).ToList();
    foreach(设置中的变量设置)
    {
    services.AddScoped(设置,serviceProvider=>
    {
    var storeId=datasettingmanager.IsDatabaseInstalled()
    ?serviceProvider.GetRequiredService()
    .GetCurrentStoreAsync().Result?.Id±0
    : 0;
    返回serviceProvider.GetRequiredService()
    .LoadSettingAsync(设置,存储ID).Result;
    });
    }
    
    MS.DI不会自动解析具体类型;它们需要明确注册。因此,NopCommerce在其
    DependencyRegister
    类(在线)中注册它们:

    //注册所有设置
    var settings=typeFinder.FindClassesOfType(typeof(ISettings),false).ToList();
    foreach(设置中的变量设置)
    {
    services.AddScoped(设置,serviceProvider=>
    {
    var storeId=datasettingmanager.IsDatabaseInstalled()
    ?serviceProvider.GetRequiredService()
    .GetCurrentStoreAsync().Result?.Id±0
    : 0;
    返回serviceProvider.GetRequiredService()
    .LoadSettingAsync(设置,存储ID).Result;
    });
    }
    
    感谢您为帮助我所做的努力,并感谢您如此全面的回答。但我仍然对在这个项目中创建具体类的对象的位置感到困惑。两个小时的时间让我摸不着头脑,但我想不出它在哪里。请阅读源代码:框架将在您需要时为您创建它。在
    的情况下,当
    取决于您的用例时;在
    的情况下,如何
    取决于什么框架。基本上,在内部,它可以使用re