ASP .NET Core Routing To Controllers in External Assembly

Viewed 4599

This is an article on ASP.NET Core routing: https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/routing

It is straight forward. I can either specify a route like this:

app.UseMvc(routes =>
{
   routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
});

Or I can mark my controllers and actions with attributes like this:

[Route("api/[controller]")]
public class TestController : Controller
{
    [HttpGet("{id}")]
    public async Task<string> Get(string id)
    {
        return "test";
    }
}

But, I tried putting a controller in an external library with attributes, and referenced that assembly from my main service, and when I punch the Url in, the call is not routed to the controller. I'm guessing I need to tell ASP.NET Core which assemblies to scan through, but I don't know how. I am using this url BTW: http://localhost:5000/api/test/a.

2 Answers

In order to tell ASP.NET Core in which assemblies it should look for controllers, you could use the concept called 'Application Parts'. There is an article on that right next to the URL that you posted in your question:

https://docs.microsoft.com/en-us/aspnet/core/mvc/advanced/app-parts?view=aspnetcore-2.0

Using that approach, you can even use controllers from the assemblies that are not referenced by your root application assembly, by loading the assemblies dynamically, based on settings in the application config file. Please refer to the example below:

public void ConfigureServices(IServiceCollection services)
{
  // ...

  // load application parts from a non-referenced 'extension' assembly:
  var path = @"c:\extensions\CustomController.dll";
  var assembly = Assembly.LoadFile(path);

  services.AddMvc()
  .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
  .AddApplicationPart(assembly);

  // ...
}

If you just reference external assembly but none of its types are explicitly used, the assembly will not be actually loaded and asp.net core will not have a chance to discover controllers within it.

To force loading of external assembly and fix your problem you could update startup routine with something simple like

var t = typeof(ExternalController);

where ExternalController is a controller from your external library.

Related