programmium

From Isham Mohamed


MVC Builder Extensions in ASP.NET Core 3.0

Disclaimer: This post was drafted on 24th September 2019 and may not be relevant for the future .NET (core (do they still call it .NET Core) in future?)) versions due to the fact that the technology is very rapidly changing and maturing.

IMvcBuilder interface is responsible for configuring MVC services in .NET Core. The service collection extension methods such as AddMvc() uses this. Starting from .NET Core 3.0, some other extension methods were introduced to ensure the modularity of the framework, this is to make sure developers are using (as they should) only the relevant features so that the execution of the application is optimal. In this post, we are going to discuss the following, assuming you have some existing knowledge in this area:

  1. AddMvcCore()
  2. AddMvc()
  3. AddControllers()
  4. AddControllersWithView()
  5. AddRazorPages()

AddMvcCore()

This provides the minimum essential MVC services. The source code located here. If you have a look at this code, it provides features such as

  • Controllers
  • Routes
  • Core Services (such as ApiBehaviorApplicationModelProvider, et al. for action discovery, ActionInvokerFactory, et al .for action invocation, etc..)

Additional services such as validation, authorization are not supported by default and validation must be added separately using the IMvcCoreBuilder returned from this extension. This is always seen as an abstract of all  It is not advised to use this in general and until ASP.NET Core 2.2, you were asked to use AddMvc().

AddMvc()

This does a lot of things by inheriting AddMvcCore() and was the de facto guy until ASP.NET Core 2.2. This provides everything for your MVC application such as:

  • API Explorer
  • Authorization
  • Views
  • Razor Pages
  • Razor View Engine
  • Tag Helpers
  • CORS
  • Data Annotations
  • JSON Formatter
  • Formatter mappings

So even if you create an API application in ASP.NET Core (it’s not called as WebAPI in ASP.NET Core, WebAPI is a traditional .NET thingy), this is the default service builder you see in the boilerplate code even though Views and Razor Pages are not relevant to an API application.

This somehow violates the molecularity of the framework. Otherwise, for a performance-critical application, you have to use AddMvcCore() and extend the pipeline, for example, AddMvcCore().AddCors() to add support for CORS.

So the folks at Microsoft reworked on that and solved the problem in ASP.NET Core 3.0 by introducing new extensions. But AddMvc() is not discontinued for ASP.NET Core 3.0. Starting from ASP.NET Core 3.0, you are advised to use one of the below extensions based on the context.

AddControllers()

Tailor-made for API applications and evolved from AddMvcCore(). By looking at the source code here,

private static IMvcCoreBuilder AddControllersCore(IServiceCollection services)
{
	// This method excludes all of the view-related services by default.
	return services
		.AddMvcCore()
		.AddApiExplorer()
		.AddAuthorization()
		.AddCors()
		.AddDataAnnotations()
		.AddFormatterMappings();
}

You can easily identify what does it do.

AddControllersWithViews()

This again evolves from AddControllers() and with that this adds the support for Views, Razor view engine, and tag helpers. This is the closest thing to AddMvc().

AddRazorPages()

Razor Pages are very similar to the old WebForms. Since razor pages are and aspect of an ASP.NET MVC application AddRazorPages() loads almost the same features as the method AddControllersWithViews() but without API Explorer, CORS and Format mapping.

So, think about the modularity and use the above methods wisely. According to the official migration document, services.AddMvc() in ASP.NET Core 3.0 is equivalent to both services.AddControllersWithViews(); services.AddRazorPages();.

Happy Coding.



Leave a comment