如何解决在构造函数中注入的具体类在哪里注册到 DI 框架?
我试图理解依赖注入,通常所有东西都是通过构造函数或属性注入注入的。
到目前为止,我已经理解它基本上围绕着接口来模拟类。
我正在检查 nop Commerce,在那里我遇到了 0x0000000000007b
,它接受几个域类,如 CustomerModelFactory
、CustomerSettings
等。
现在,当我检查 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种方法可以让你获得一个对象的实例
- 需要时直接创建实例
CustomerSettings settings = new CustomerSettings();
- 在需要时通过反射创建实例
Type t = typeof(CustomerSettings);
CustomerSettings settings = Activator.CreateInstance(t) as CustomerSettings;
- 在字典中缓存所有实例并在使用类型名称时查找
事情可能是这样的:
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 举报,一经查实,本站将立刻删除。