Full source code available here.
Did you know that .NET Core 2 can pass in an instance of any type you want to the Startup.cs
constructor? Well you can! Here’s how.
Out of the box the Startup.cs
comes like this –
public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } //snip..
The IConfiguration
is passed in by dependency injection. In Program.cs
you can add other types to the DI container, and then add that type to the constructor parameters of Startup.cs
.
Here’s how it works. The Microsoft.AspNetCore.Hosting.WebHostBuilder
has a ConfigureServices(...)
method –
public IWebHostBuilder ConfigureServices(Action<IServiceCollection> configureServices) { if (configureServices == null) { throw new ArgumentNullException(nameof(configureServices)); } return ConfigureServices((_, services) => configureServices(services)); }
This lets you add services to the dependency injection container from the Program.cs
.
WebHost.CreateDefaultBuilder(args)
returns an IWebHostBuilder
and that lets you use the ConfigureServices(...)
method. Easy!
public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .ConfigureServices(serviceCollection => serviceCollection.AddScoped<ISomeService, SomeService>()) .UseStartup<Startup>() .Build();
And in Startup.cs
–
public class Startup { private ISomeService _someService; public Startup(IConfiguration configuration, ISomeService someService) { _someService = someService; Configuration = configuration; } // snip..
The instance of ISomeService
is of course available for DI everywhere in the application.
public class ValuesController : Controller { private readonly ISomeService _someService; public ValuesController(ISomeService someService) { _someService = someService; } }
Full source code available here.
AddScoped is missing? Do you know why?
Hi Gelo,
Where is
AddScoped
missing from?Bryan
Pingback: Dynamically Updating the Request Header of a HttpClientFactory Generated HttpClient | no dogma blog
Pingback: How to Dependency Inject a Service from Startup back in Program | no dogma blog
Works perfectly – and that’s exactly what I am trying to do. However, when I updated to ASP.NET Core 3, it throws exception:
InvalidOperationException: Unable to resolve service for type ‘DIAndTheStartup.ISomeService’ while attempting to activate ‘DIAndTheStartup.Startup’.
Any thoughts how it should be modified for Core 3?
I can see *why* it’s throwing an exception: https://docs.microsoft.com/en-us/dotnet/core/compatibility/2.2-3.1#hosting-generic-host-restricts-startup-constructor-injection
But I don’t understand what to do if I need the injected service in ConfigureServices!
There have been problems with the DI container see this – https://twitter.com/davidfowl/status/1038521947007594498.
Are you trying to use a service that you are adding to the DI container, within the ConfigureServices method?
If so, consider using it in the Configure() method instead. In this post https://nodogmablog.bryanhogan.net/2018/11/caching-in-polly-6-and-the-httpclientfactory/ I register services in ConfigureService() then use them in Configure().