C# 在DI框架中注册的构造函数中注入的具体类在哪里?
我试图理解依赖项注入,通常所有东西都是通过构造函数或属性注入注入的 到目前为止,我了解到它基本上是围绕接口来模拟类的 我正在查看Nop Commerce,在那里我遇到了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的新实例 所以我的问题是,当我
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