[英]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,如CustomerSettings
、 DatetimeSettings
等。
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的实例
CustomerSettings settings = new CustomerSettings();
Type t = typeof(CustomerSettings);
CustomerSettings settings = Activator.CreateInstance(t) as CustomerSettings;
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
。
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.