ASP.NET Core

From the last dispatch

We had spent time in understanding the change in position from ASP.NET web app hosting. The change in stand lead to way the web app starts and loads in memory. It gave way to be able to move away from IIS and host the ASP.NET application from console. In fact, if you inspect the bin folder after you compile a basic ASP.NET core web app, you will notice a [solution name].exe file contrary to the earlier versions where you will get only a dll file.

We looked at Program.cs which is the entry point for web app. However, do keep in mind that it is not the entry point for the HTTP request. It hosts the entry point only for the app to bootstrap by a hosting environment. Once that comes up it is the middleware which welcomes and handles each and every HTTP request.

In Program.cs we noticed how entire infrastructure is bootstrapped and a default infrastructure could as well be initialized without having to install a separate server executable like IIS. Thus, in summary Program.cs hosts the main method and code for the infrastructure needed to run the app.

ConfigureHost vs ConfigureApp

There is a subtle difference which is worth highlighting. In our last dispatch we used a code –

var host = new HostBuilder().

    ConfigureHostConfiguration(…).

    ConfigureAppConfiguration(…).

    ConfigureServices(…).

    ConfigureLogging(…)

Here we have both ConfigureHostConfiguration and ConfigureAppConfiguration. Both have identical signature where to enforce the pipeline processing pattern they consume IHostBuilder and return IHostBuilder. They both take parameter of type delegate typed on IConfigurationBuilder. The difference between them is more conventional.  Configurations like what is the root folder, which type of process will handle the HTTP request etc are configured in the delegate passed to ConfigureHostConfiguration. For the ConfigureAppConfiguration, the simplest way to put is – Remember the appSettings section in ASP.NET web.config from yester years. That method is responsible for configuring such elements which are central to your application.

The last thing is how do one read these configurations. Brining from the earlier dispatch, if the following was the key sent to configure the app –

myapp.exe –databaseName guests -connectionString=”…” /allowedRoles “{…}”

Developer can read the value for databaseName as follows –

using Microsoft.Extension.Configuration;

… (IConfiguration config) {

   var dbName = config.GetValue<string>(“databaseName”);

}

There is another way to accomplish the same but is not recommended i.e. indexer style usage of the config object

var dbName = config[“databaseName”] as string;

Startup.cs

We have spent much time deliberating about Program.cs. In other words, the host configuration by and large. There is a very crucial element that gets packaged in that configuration. i.e. the Startup file. The reason this is bit confusing is because it uses convention and with help of reflection does much of the Host configuration instead of using abstraction and interface implementation.

If you resonate with that thought, there is this class StartupBase in Microsoft.AspNetCore.Hosting. Though we could not think of practically any variety in middleware and in hosting configuration you will need between dev and test. However, there are scenarios where you will need a different middleware for microservices based on the capability it offers in the entire architecture. E.g could be same aspnet core web app processes files which are lightweight like CSV and TSV as a single microservice. You know that this service is mostly consumed and is less error prone. However, you also have the necessity to process Excel file which contain multiple sheets and have complex cell (de)merge as input file. Microservice for this uses same aspnet core app but now has additional logging to diagnose any failure. The same situation could be extended a bit where in the middleware each worksheet in the excel file is split to a CSV and the microservice which you used earlier could be used again. Such, complex orchestration most of the time is rather simple with multiple Startup.cs files with different configuration for host rather than entire code base reproduced in different folders.

Over years many ASP.NET applications have shaped up the current ASP.NET core framework. Services like dependency injection was not native to ASP.NET framework per-se. However, in the core framework it is a first-class citizen. Startup class is responsible for making such things available for the application to focus on business logic. Isn’t that the only reason why developers pick a framework over another to code?

A vanilla out of project template default Startup looks like this –

public Startup(IConfiguration config) {…}

public void Configure(IApplicationBuilder app, IHostEnvironment env) {…}

public void ConfigureServices(IServiceCollection svc) {… }

This is all, that is all the rule one has to remember. A constructor with IConfiguration, a Configure method with 2 parameters and a ConfigureServices method with just 1 parameter. If you notice we have already followed convention in the manner like –

1. Constructor
2. and Name of the methods

However, the convention does not end there it is possible that you could use different Startup file for each environment. Environments are again by convention available as Development, Staging and Production. So, one could have either / or / and StartupDevelopment.cs as class name or ConfigureStaging as method name. This gives a great deal of flexibility in terms of the way one can accomplish customized approach for appropriate treatment for the environment.

Configure and ConfigureServices differ in nearly the same way as ConfigureHostConfiguration and ConfigureAppConfiguration differ. i.e. Configure is used to setup the Host with root folder, exception redirect strategy, allow static files to be served, use of https always etc. those which in earlier days would have been done in a website folder in IIS Manager. ConfigureServices sets up a default dependency injection container which is used to configure all Services that app needs and other features like Authentication service, View collection, Antiforgery token generation etc. kind of services which you might have added in Web.config file in ASP.NET world.

Hope you do now look in these defaults and customize it to the use case as needed by making the enigmatic Startup a more of enchanted Startup in the aspnet core world. Happy programming.