c# - .Net Core Dependency injection services.Add vs services.Replace
问题描述
例如,使用 services.(AddScoped, AddTransient, AddSingleton) 和 service.replace 注入服务有什么区别
services.AddScoped<IPasswordHasher<ApplicationUser>, SqlPasswordHasher<ApplicationUser>>();
services.Replace(new ServiceDescriptor(
serviceType: typeof(IPasswordHasher<ApplicationUser>),
implementationType: typeof(SqlPasswordHasher<ApplicationUser>),
ServiceLifetime.Scoped));
解决方案
可以在源代码中看到差异。
第一个是IServiceCollection
接口,是依赖注入的核心接口。
public interface IServiceCollection : IList<ServiceDescriptor>
{
}
IServiceCollection
只是一个ServiceDescriptor
对象列表。ServiceDescriptor
描述注入类型的信息。
基于这个接口,可以对这两种方法Add
进行Replace
讨论。
public static IServiceCollection Add(
this IServiceCollection collection,
ServiceDescriptor descriptor)
{
...
collection.Add(descriptor);
return collection;
}
public static IServiceCollection Replace(
this IServiceCollection collection,
ServiceDescriptor descriptor)
{
...
// Remove existing
int count = collection.Count;
for (int i = 0; i < count; i++)
{
if (collection[i].ServiceType == descriptor.ServiceType)
{
collection.RemoveAt(i);
break;
}
}
collection.Add(descriptor);
return collection;
}
Add
只是将服务描述符推送到列表中,同时Replace
首先检查并删除列表中具有相同服务类型的描述符,最后将当前描述符添加到列表中。
因此,这两种方法的时间复杂度是不同的。大多数情况下的时间复杂度Add
是O(1),Replace
而是O(n)(遍历列表)。但是,Add
不保证添加的描述符是唯一的,而是Replace
会删除具有相同服务类型的描述符并添加当前的描述符。
推荐阅读
- python - 无法将系列转换为
? - vue.js - 无法读取 v-file-input Vuetify 的未定义属性“长度”
- jboss-eap-7 - JBoss 7.1.0:将默认发件人添加到邮件子系统
- javascript - JSON 到 JavaScript 变量通过 AJAX 和 PHP MYSQL => Array undefined
- material-ui - 如何在 TextField 中使用 ref
- javascript - 如何使用 Angular 7 中的自定义过滤器和复选框过滤列表
- java - 数据库全文检索
- python - Matplotlib:概率质量图
- selenium - Selenium Grid 的确切用途是什么?
- javascript - 将数字字符串数组映射到整数返回 NaN