How to register MVC controllers shipped with a class library in ASP.NET Core
In many cases you’ll want to ship MVC controllers, possibly views or taghelpers, etc… as part of your class library. To do this correctly you’ll want to add your assembly to ASP.NET’s “Application Parts” on startup. Its quite simple to do but you might want to make sure you are not enabling all sorts of services that the user of your library doesn’t need.
The common way to do this on startup is to have your own extension method to “Add” your class library to the services. For example:
public static class MyLibStartup
{
public static IServiceCollection AddMyLib(this IServiceCollection services)
{
//TODO: Add your own custom services to DI
//Add your assembly to the ASP.NET application parts
var builder = services.AddMvc();
builder.AddApplicationPart(typeof(MyLibStartup).Assembly);
}
}
This will work, but the call to AddMvc() is doing a lot more than you might think (also note in ASP.NET Core 3, it’s doing a similar amount of work). This call is adding all of the services to the application required for: authorization, controllers, views, taghelpers, razor, api explorer, CORS, and more… This might be fine if your library requires all of these things but otherwise unless the user of your library also wants all of these things, in my opinion it’s probably better to only automatically add the services that you know your library needs.
In order to add your assembly application part you need a reference to IMvcBuilder which you can resolve by calling any number of the extension methods to add the services you need. Depending on what your application requires will depend on what services you’ll want to add. It’s probably best to start with the lowest common feature-set which is a call to AddMvcCore(), the updated code might look like this:
//Add your assembly to the ASP.NET application parts
var builder = services.AddMvcCore();
builder.AddApplicationPart(typeof(MyLibStartup).Assembly);
From there you can add the other bits you need, for example, maybe you also need CORS:
//Add your assembly to the ASP.NET application parts
var builder = services.AddMvcCore().AddCors();
builder.AddApplicationPart(typeof(MyLibStartup).Assembly);