I’m writing this for those new to ASP.NET Core, based on what I see on StackOverflow. Most of what I’ve written here is already in the Docs, so check the links at the end of the post for detailed info.
The ASP.NET Core Web Host
Think of the web host as an instance of an application server that processes incoming web requests. We create one (usually in Program.cs) as follows:
1public static void Main(string[] args) =>
2 CreateHostBuilder(args).Build().Run();
3
4public static IHostBuilder CreateHostBuilder(string[] args) =>
5 Host.CreateDefaultBuilder(args)
6 .ConfigureWebHostDefaults(webBuilder =>
7 webBuilder.UseStartup()
8 );
The CreateDefaultBuilder() sets up the app’s configuration. Source (v3.0.0). The app’s configuration is represented by the IConfiguration interface. (You can also manually create your own WebHostBuilder instance if the defaults don’t work for you, in which case you’re responsible for setting up the app configuration.)
When the WebHost is built using Build(), your startup class’s ConfigureServices() is called. See WebHostBuilder.cs L187, WebHost.cs L110 and WebHost.cs L180.
Using IConfiguration in Startup
You can get an instance of IConfiguration for use in your Startup class by constructor injection:
1public class Startup
2{
3 private IConfiguration Configuration { get; }
4 public Startup(IConfiguration configuration) // The whole point of `IConfiguration` is to provide a way through which the .NET Core app can read configuration from different sources: configuration files, environment variables, command line arguments, etc.
5## Using IConfiguration outside Startup
6
7You can also inject an `IConfiguration` instance almost anywhere:
8
9```csharp
10public class EmailSender
11{
12 private string ClientKey { get; }
13 private string ClientSecret { get; }
14
15 public EmailSender(IConfiguration configuration)
16 {
17 ClientKey = configuration["ClientKey"];
18 ClientSecret = configuration["ClientSecret"];
19 }
20
21 // rest of the class follows...
22}
Let’s just stop for a while and imagine an example: we’re in a controller’s action and need to send an email. We get an EmailSender instance from DI, and use it to send the email. The EmailSender gets email credentials from the IConfiguration abstraction. It doesn’t need to know where it’s coming from: appsettings.json, command-line arguments, environment variables, azure vault storage– could be coming from anywhere and EmailSender doesn’t need to care about it.
There are still areas left wanting though:
- The configuration is not strongly typed: non-string values will need to be manually parsed.
- The email sender above requires
ClientKeyandClientSecretto be defined using the exact configuration keys. SoEmailSenderis sort-of coupled with the way the actual configuration is set.
The solution to these is the Options Pattern.
Options Pattern
Think of this as an additional layer of abstraction. In the EmailService example, we’d replace IConfiguration with IOptions. IConfiguration knew how to get the right configuration from the right places for you, IOptions knows how to get the relevant configuration from IConfiguration for you.
Here’s a simplified way to use it:
- Group related settings together in your
appsettings.json:
1{
2 "Email": { // 2. Create a class to hold those settings:
3
4```csharp
5public class EmailOptions
6{
7 public string ClientKey { get; set; }
8 public string ClientSecret { get; set; }
9}
- Register the Options with the DI container:
1services.Configure4. Inject it into the service that needs it:
2
3```csharp
4public class EmailSender
5{
6 private string ClientKey { get; }
7 private string ClientSecret { get; }
8
9 public EmailSender(IOptions options) //
10
11Follow this, and you won't see the need to inject `IConfiguration` anywhere outside `Startup`.
12
13---
14
15###### Microsoft Docs links:
16
17- [Configuration in ASP.NET Core](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1)
18- [Options pattern in ASP.NET Core](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-3.1)
19- [ASP.NET Core Web Host](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/web-host?view=aspnetcore-3.1)