Home > Software design >  Does RequestServices.GetService() have a significant impact on performance
Does RequestServices.GetService() have a significant impact on performance

Time:09-23

Is RequestServices.GetService() an expensive operation? Is it a bad practice to use GetService() in a method if you cannot get services in the constructor?

Note: I am not asking if Dependency Injection is performant. I am asking if using RequestServices.GetService() inside a method (where you can's use DI such as in a custom attribute) is a bad idea, or is it essentially equivalent in performance to 'normal' constructor based DI.

I am using a custom attribute in an Asp.Net MVC Core application. In the OnAuthoizationAsync() method, I need to access a configuration setting. As my class inherits from 'Attribute', I cannot use DI to pass an object into the constructor. I am using the HttpContext.RequestServices.GetService() method to get the instance of configuration. The custom attribute could run on most requests, so it cannot have a big performance impact.

public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
   var config = (IConfiguration)context.HttpContext.RequestServices.GetService(typeof(IConfiguration));
    ...
}

CodePudding user response:

Since the method is run for (almost) every request, the dependency is also resolved at every request.

The cost of resolution is usually a non-issue, unless you're using a custom DI provider (Autofac) and have complex rules for type resolution. But Microsoft's DI purposefully keeps things simple, which speeds up type resolution.

Additionally, you might need to consider the dependency lifetime. If the type is added to DI as a transient, it's allocated & created every time you resolve it (i.e. every time the method is executed)

If it's scoped, it's allocated once per request. So if the attribute is used multiple times, only a single object is created and returned when you resolve a type. So you pay the price once per request.

If it's singleton, it's allocated once per (app/DI container) lifetime, so you pay the price only once.

So if the type is large and slow to create, it might create some overhead, but you can avoid it by conditionally resolving it under some ifs, for example. All things considered, it's almost certainly a fraction of the time spent when doing IO, so I'd not worry about it.

  • Related