ASP.Net Core application starts its execution with the program.cs file where we have a Main Method and this method is the starting point of the application.
Generally whenever we create a new ASP.NET Core Web Application project we have two files named Program.cs and Startup.cs files. Program.cs file contains the Main method which calls Host builder and it calls the Startup class which is configured using .UseStartup(). The UseStartup accepts generic arguments so it can take any class as input and use that as a Startup class. The startup class in Dotnet Core is similar to the Global.asax file in traditional .Net and runs only when the application starts bootstrapping itself.
Program.cs File
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
The startup file contains two important methods namely ConfigureServices and Configure which registers all the necessary dependency and middleware required to run the application.
Startup.cs File
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
}
ConfigureServices Method
As the name suggests ConfigureServices configures all the required services required to run the application. ASP.NET Core architecture provides a built-in dependency injection feature to register all the dependent services using constructors.
ConfigureServices method takes IServiceCollection as a parameter to register services to IoC Container. Suppose we have StudentController class that uses StudentService class to do the CRUD operations for students then we can register that dependency like below
services.AddTransient<IStudentService, StudentService>();
Similarly, if we can register the dependency for DbContext Class then it can be done as below
services.AddDbContext<DbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("StudentContext")));
Services Lifetimes
Services in ASP.NET Core architecture can be registered in three ways
- AddTransient(): Transient Lifetime services are created each time they are requested. Generally, it is used for lightweight and stateless services.
- AddScoped(): Scoped Lifetime services are created once per request lifecycle. It means once in HTTP request if you request services for 5 times then it will return the same instance. The IoC container disposes of the scoped object at the end of an HTTP request. It's generally used for repository class where it uses the same repository object within the same request.
- AddSingleton(): Singleton instance is created only once for the entire life cycle of the application. It will return the same instance irrespective of any number of HTTP Requests. Example usage of Singleton lifetime is when we want to register Logging Services or caching services which remain the same for the entire life cycle of the application. Singleton services should be memory-efficient and thread-safe otherwise we could end in a memory leak or multi-threading issue in the application.
In large web applications where we have many services classes to be registered, we can split the registration into multiple classes and use the extension method in the ConfigureServices method.
Suppose we want to register all the repositories in separate class like below
public static class DependencyRegistrations
{
public static IServiceCollection RegisterRepositories(this IServiceCollection services)
{
services.AddScoped<IUserRepository, UserRepository>();
services.AddScoped<IStudentRepository, StudentRepository>();
return services;
}
}
Now we can use the above RegisterRepositories extension method in the ConfigureServices method like below
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.RegisterRepositories();
}
The above approach is very useful to achieve clean code as registering all your repositories in the ConfigureServices method will make the method too long and difficult to read.
Configure Method
The Configure method is invoked in the ASP.NET Core application after the ConfigureServices method and its basic purpose is to configure the HTTP request pipeline of the application using middlewares.
Ordering of middleware matters in Configure method so the middleware mentioned first will process the request first and then the second middleware. For example, If certain middleware is to authenticate the request coming into the application and authentication is successful then it passes the request to the next middleware and if authentication fails then it returns the requests with 401 unauthorized responses.
Configure method uses two services which are as follows
IApplicationBuilder: It is used to configure the application request pipeline and has several extension methods to configure the application's request pipeline.
Following are the common middleware used in Web Application
- UseCors(): Adds a CORS middleware to your web application to allow cross-domain requests.
- UseRouting(): Defines the routing for the application.
- UseDevelopmentExceptionPage(): Captures exception instance from the pipeline and generates HTML error response.
- UseHttpsRedirection(): Redirects HTTP requests to HTTPS.
We can also create our custom middleware and register in Configure method.
IWebHostEnvironment: It provides information about the web hosting environment in which the application runs like Environment name, WebRoot path, Content Root path, etc... . IHostingEnvironment was used for a similar purpose in earlier versions of ASP.NET CORE application.
It also provides some extension methods which are as follows:
- IsDevelopment(): Check whether the hosting environment is Development.
- IsEnvironment(): Compares the environment name against the specified value.
Difference between ConfiguresServices and Configure Method
- ConfiguresServices is basically used for registering the services required to run the application whereas Configure method helps us to configure the middlewares used in the HTTP request pipeline.
- Ordering matters in Configure method because middlewares are invoked as per the order mentioned in the method whereas Ordering of Services registered hardly matters in ConfigureServices method.
- ConfigureServices method is invoked first when application starts whereas Configure method is invoked after ConfigureServices method.
- ConfigureServices method takes IServicesCollection services as a parameter which help to register services in the application whereas Configure method take IApplicationBuilder and IWebHostEnvironment services as parameter to configure middlewares like routing, CORS, etc.
There is one more services which is available for injection in ASP.NET Core application i.e. ILoggerFactory which provides a mechanism for creating loggers.
Note this article is only valid till ASP.NET CORE 3.1 version and in the new version of ASP.NET CORE i.e. version 6 we don't have any ConfigureServices and Configure method as well as startup class. We have only Program.cs file in ASP.NET CORE version 6 which don't have any Main method as well.
I will the cover those differences in a separate article.
Share This Post
Support Me