register Web API controller from class library
I have a working solution on my computer.
Solving the problem
It turns out it's actually really simple. MVC loads ApplicationPart
s from different assemblies. In a normal web application setup, this seems to be picked up properly, even when using Razor Class Libraries. However, when using a worker service and either a library, or a Razor Class Library, it doesn't work, and so the route for your controller isn't registered.
To add the library as an application part, open up the IServiceCollectionExtensions
class you created, and change it to this:
public static class IServiceCollectionExtensions
{
public static IServiceCollection AddLibrary(this IServiceCollection services)
{
services
.AddControllers()
// Notice the assembly is the type of this class, as this
// is the assembly the controller is in.
// You'll have to call this for every assembly you have
// controllers in, except for any controllers
// you might put in your worker service project.
.AddApplicationPart(typeof(IServiceCollectionExtensions).Assembly);
return services;
}
}
Now, starting the app and sending a request to http://localhost:5000/users
will work. I've confirmed this works for both libraries and Razor Class Libraries.
I should also say that controllers in the worker service project itself will work as normal - there is no special setup required for those.
Things you don't need
- You don't need the call to
services.AddMvc()
inIServiceCollectionExtensions
. Calling this, without parameters, is the same as callingAddControllersWithViews()
andAddRazorPages()
. - You don't need the
Microsoft.AspNetCore.Mvc.Core
package in your library project - mine runs fine just with the framework reference you added. The only package I have in there is forMicrosoft.AspNetCore.Server.Kestrel.Core
.