[c#] Resolving instances with ASP.NET Core DI from within ConfigureServices

The IServiceCollection interface is used for building a dependency injection container. After it's fully built, it gets composed to an IServiceProvider instance which you can use to resolve services. You can inject an IServiceProvider into any class. The IApplicationBuilder and HttpContext classes can provide the service provider as well, via their ApplicationServices or RequestServices properties respectively.

IServiceProvider defines a GetService(Type type) method to resolve a service:

var service = (IFooService)serviceProvider.GetService(typeof(IFooService));

There are also several convenience extension methods available, such as serviceProvider.GetService<IFooService>() (add a using for Microsoft.Extensions.DependencyInjection).

Resolving services inside the startup class

Injecting dependencies

The runtime's hosting service provider can inject certain services into the constructor of the Startup class, such as IConfiguration, IWebHostEnvironment (IHostingEnvironment in pre-3.0 versions), ILoggerFactory and IServiceProvider. Note that the latter is an instance built by the hosting layer and contains only the essential services for starting up an application.

The ConfigureServices() method does not allow injecting services, it only accepts an IServiceCollection argument. This makes sense because ConfigureServices() is where you register the services required by your application. However you can use services injected in the startup's constructor here, for example:

public Startup(IConfiguration configuration)
{
    Configuration = configuration;
}

public IConfiguration Configuration { get; }

public void ConfigureServices(IServiceCollection services)
{
    // Use Configuration here
}

Any services registered in ConfigureServices() can then be injected into the Configure() method; you can add an arbitrary number of services after the IApplicationBuilder parameter:

public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<IFooService>();
}

public void Configure(IApplicationBuilder app, IFooService fooService)
{
    fooService.Bar();
}

Manually resolving dependencies

If you need to manually resolve services, you should preferably use the ApplicationServices provided by IApplicationBuilder in the Configure() method:

public void Configure(IApplicationBuilder app)
{
    var serviceProvider = app.ApplicationServices;
    var hostingEnv = serviceProvider.GetService<IHostingEnvironment>();
}

It is possible to pass and directly use an IServiceProvider in the constructor of your Startup class, but as above this will contain a limited subset of services, and thus has limited utility:

public Startup(IServiceProvider serviceProvider)
{
    var hostingEnv = serviceProvider.GetService<IWebHostEnvironment>();
}

If you must resolve services in the ConfigureServices() method, a different approach is required. You can build an intermediate IServiceProvider from the IServiceCollection instance which contains the services which have been registered up to that point:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IFooService, FooService>();

    // Build the intermediate service provider
    var sp = services.BuildServiceProvider();

    // This will succeed.
    var fooService = sp.GetService<IFooService>();
    // This will fail (return null), as IBarService hasn't been registered yet.
    var barService = sp.GetService<IBarService>();
}

Please note: Generally you should avoid resolving services inside the ConfigureServices() method, as this is actually the place where you're configuring the application services. Sometimes you just need access to an IOptions<MyOptions> instance. You can accomplish this by binding the values from the IConfiguration instance to an instance of MyOptions (which is essentially what the options framework does):

public void ConfigureServices(IServiceCollection services)
{
    var myOptions = new MyOptions();
    Configuration.GetSection("SomeSection").Bind(myOptions);
}

Manually resolving services (aka Service Locator) is generally considered an anti-pattern. While it has its use-cases (for frameworks and/or infrastructure layers), you should avoid it as much as possible.

Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to dependency-injection

Are all Spring Framework Java Configuration injection examples buggy? Passing data into "router-outlet" child components ASP.NET Core Dependency Injection error: Unable to resolve service for type while attempting to activate Error when trying to inject a service into an angular component "EXCEPTION: Can't resolve all parameters for component", why? org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'demoRestController' How to inject window into a service? How to get bean using application context in spring boot Resolving instances with ASP.NET Core DI from within ConfigureServices How to inject a Map using the @Value Spring Annotation? WELD-001408: Unsatisfied dependencies for type Customer with qualifiers @Default

Examples related to asp.net-core

dotnet ef not found in .NET Core 3 How to use Bootstrap 4 in ASP.NET Core ASP.NET Core - Swashbuckle not creating swagger.json file Getting value from appsettings.json in .net core .net Core 2.0 - Package was restored using .NetFramework 4.6.1 instead of target framework .netCore 2.0. The package may not be fully compatible Automatically set appsettings.json for dev and release environments in asp.net core? Get ConnectionString from appsettings.json instead of being hardcoded in .NET Core 2.0 App Unable to create migrations after upgrading to ASP.NET Core 2.0 EF Core add-migration Build Failed ASP.NET Core form POST results in a HTTP 415 Unsupported Media Type response

Examples related to asp.net-core-mvc

Getting value from appsettings.json in .net core Unable to create migrations after upgrading to ASP.NET Core 2.0 ASP.NET Core form POST results in a HTTP 415 Unsupported Media Type response ASP.NET Core Get Json Array using IConfiguration ASP.NET Core Dependency Injection error: Unable to resolve service for type while attempting to activate How do I access Configuration in any class in ASP.NET Core? How to register multiple implementations of the same interface in Asp.Net Core? ASP.NET Core Identity - get current user How to get current url in view in asp.net core 1.0 How to return HTTP 500 from ASP.NET Core RC2 Web Api?