If you’ve started a new ASP.NET Core project recently, chances are you would have seen the following lines :
public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .Build();
And chances are, you’ve also followed a tutorial that was written about a year ago that doesn’t include this line and instead has this big long winded builder instead :
var host = new WebHostBuilder() .UseKestrel() .UseContentRoot(Directory.GetCurrentDirectory()) .UseIISIntegration() .UseStartup<Startup>() .Build();
Or maybe you could be coming here because you’ve been told to add the following configuration lines somewhere in your code :
var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
But yours just “works” without it. Somehow. Magically.
I know that people comment on old tutorials from 2+ years ago that their boilerplate code no long matches what they get when creating a new project in Visual Studio. I’ve thought about going back and editing all tutorials, but instead I felt it was important to understand the simplicity of what’s going on here and that it’s really not such a big deal.
Let’s demystify.
Opening Up The Code
Before we go much further I have to say that until a few years back, I probably wasn’t as big on the open source train as I could be. But with ASP.NET being open source, I lost count of how many times I just skipped the documentation and went to the actual source code to work out what was going on or how I should approach something. This is one of those times!
We can actually head to the source code for CreateDefaultBuilder and take a look!
public static IWebHostBuilder CreateDefaultBuilder(string[] args) { var builder = new WebHostBuilder(); [...] builder.ConfigureAppConfiguration((hostingContext, config) => { var env = hostingContext.HostingEnvironment; config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true); [...] }) [...] }
I’ve removed a lot of code for brevity. But as we can see, the CreateDefaultBuilder actually adds in both appsettings.json and the appsettings for our current environment. Hence why we don’t see configuration code being required elsewhere!
If we look deeper into the code we can actually see it doing a lot more of the work that we previously had to build ourselves.
What Else Is Done For Us?
When we use the CreateDefaultBuilder method, out of the box we get :
- Sets the “Content Root” to be the current directory
- Allows Command Line args to be pushed into your configuration object
- Adds both appsettings.json and appsettings.{Environment}.json to be loaded into the configuration object
- Adds environment variables to the configuration object
- If in Development, allows the loading of secrets.
- Adds Console/Debug loggers
- Tells the app to use Kestrel and to load Kestrel configuration from the loaded config
- Adds Routing
- Adds IIS Integration
That sounds like a lot, but if we again go back to what we used to write :
var host = new WebHostBuilder() .UseKestrel() .UseContentRoot(Directory.GetCurrentDirectory()) .UseIISIntegration() .UseStartup<Startup>() .Build();
It’s just now doing all of this under the hood for us (and more!). Nice!