RequestServices.GetService()对性能影响大吗

问题描述 投票:0回答:2

RequestServices.GetService() 是一个昂贵的操作吗?如果无法在构造函数中获取服务,那么在方法中使用 GetService() 是一种不好的做法吗?

注意:我不是问依赖注入是否高效。我问在方法内部使用 RequestServices.GetService() 是否是一个坏主意(您可以在其中使用 DI,例如在自定义属性中),或者它在性能上是否与基于“正常”构造函数的 DI 基本相同。

我在 Asp.Net MVC Core 应用程序中使用自定义属性。在 OnAuthoizationAsync() 方法中,我需要访问配置设置。由于我的类继承自“Attribute”,因此我无法使用 DI 将对象传递到构造函数中。我正在使用 HttpContext.RequestServices.GetService() 方法来获取配置实例。自定义属性可以在大多数请求上运行,因此不会对性能产生很大影响。

public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
   var config = (IConfiguration)context.HttpContext.RequestServices.GetService(typeof(IConfiguration));
    ...
}
c# asp.net-core .net-core
2个回答
1
投票

由于(几乎)每个请求都会运行该方法,因此每个请求也会解析依赖关系。

解析成本通常不是问题,除非您使用自定义 DI 提供程序 (Autofac) 并且具有复杂的类型解析规则。但 Microsoft 的 DI 有意让事情变得简单,从而加快了类型解析速度。

此外,您可能需要考虑依赖项生命周期。如果该类型作为瞬态添加到 DI 中,则每次解析它时(即每次执行该方法时)都会分配并创建它

如果有范围,则每个请求分配一次。因此,如果多次使用该属性,则在解析类型时只会创建并返回一个对象。因此,您每个请求只需支付一次价格。

如果是单例,则每个(应用程序/DI 容器)生命周期分配一次,因此您只需支付一次价格。

因此,如果类型很大并且创建速度很慢,则可能会产生一些开销,但是您可以通过例如在某些

if
下有条件地解析它来避免这种情况。 考虑到所有因素,这几乎肯定只是执行 IO 所花费时间的一小部分,所以我不担心它。


0
投票

我也对此感兴趣。由于 .NET 现在是开源的,您可以... look

结果在内部,服务提供者使用了

ConcurrentDictionary
访问器。因此
GetService
添加的开销 - 只是在字典中查找定位器委托。

字典查找是

O(1)
(如“常数,无论字典大小如何)。

我仍然写了一个基准测试,在我的机器上需要

9.448ns
(九纳秒)。

方法 意思是 错误 标准偏差 比率 比率SD 已分配 分配比例
Direct_Var_Ascess 4.399 纳秒 0.1896 纳秒 0.0104 纳秒 1.00 0.00 - 不适用
AsyncLocal_Cache 7.374 纳秒 1.6657 纳秒 0.0913 纳秒 1.68 0.02 - 不适用
服务查找 9.448 纳秒 0.4034 纳秒 0.0221 纳秒 2.15 0.01 - 不适用

在这里,我直接访问一个对象,然后在

AsyncLocal
变量中访问它(我认为缓存服务可能会使其更快?),然后最后使用
GetService

结论是 - 忘记它。

附注另请参阅有关依赖生命周期的其他答案。

© www.soinside.com 2019 - 2024. All rights reserved.