ASP.NET Core – ConfigureServices vs Configure
Introduction
We already talked about Configuration method inside of Startup when we talked about requests and middleware. In this post, we will see what exactly ConfigureServices and Configure methods are for and how they differ.
In ASP.NET Core we have a Startup class where all the configuration is done and processed once the application is starting.
When we create a new simple web application using dotnet CLI:
dotnet new web
we will get this code:
public class Startup { // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.Run(async (context) => { await context.Response.WriteAsync("Hello World!"); }); } }
ConfigureServices
Even though we will almost always use this method, it is an optional method.
If ConfigureServices exists on Startup class, it will be called by the Web host. Of course, for this to happen Web host has to instantiate Startup first. Therefore, Startup constructor will execute before ConfigureServices. We will usually have our configuration and logging setup inside of the constructor.
You will notice that by default ConfigureServices has one parameter, of type IServiceCollection. IServiceCollection is a container. Adding services to this container will make them available for dependency injection. That means we can inject those services anywhere in our application.
Let’s see an example:
public void ConfigureServices(IServiceCollection services) { services.AddSingleton<IEmailSender, EmailSender>(); }
Now we can use IEmailSender anywhere we want. For example:
public HomeController(IEmailSender emailSender) { }
Now we can access an instance of IEmailSender in our controller. And later on, we can replace the concrete implementation of this interface inside of our ConfigureServices method with something else.
We can also add an instance of the class to DI directly.
public void ConfigureServices(IServiceCollection services) { var helper = new Helper(); services.AddSingleton(helper); }
And now we would do the following to use the Helper instance in the controller:
public HomeController(Helper helper) { }
Even for MVC framework itself, you will need to add it inside of ConfigureServices:
public void ConfigureServices(IServiceCollection services) { services.AddMvc(); }
Configure
Inside of Configure method we set up middleware that handles every HTTP request that comes to our application:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseBrowserLink(); app.UseMvc(); }
We should keep our Configure method clean and in the case of having large chunks of code that are processing request we should move those to our middleware.
Ordering matters in Configure method, so first piece of code inside of the method will process the request first. It can either make a response or pass the request to the next piece of middleware.
Summary
- ConfigureServices is used to add services to our application
- We can use services via integrated DI once we add them inside of ConfigureServices
- Services added to DI can be utilised within our application
- Configure method is used to set up middleware
- We manage HTTP request pipeline inside of Configure method
- Inside of Configure method, we write code that will process every request and eventually make a response