Using controllers from an external assembly in ASP.NET Web API

In general, in my day-to-day job, I am working with large enterprise web applications, where clean projects, noise reduction and test driven development are holy. Therefore I have always been a big fan of placing MVC controllers outside the actual web application project, in a separate class library (or libraries).

With MVC it was very simple, but recently I faced this challenge in Web API, and turns out neither passing the assembly name through MapHttpRoute (not supported) or using something like ControllerBuilder.Current.DefaultNamespaces is not a viable option. So I turned to Henrik Nielsen for advice, and sure enough, he helped immediately. Let’s explore the solution.

The solution

The solution to our problem is to write a custom class implementing IAssemblyResolver, hook it up to the GlobalConfiguration and add a list of our additionally required assemblies there.

Let’s assume we have our controllers in a library called ControllersLibrary, and it is a regular class library, located at c:/libs/controllers/ControllersLibrary.dll.

If you are not used to that concept, think about that for a second. Controllers don’t really need Global.asax or anything else the web application provides; they might as well live elsewhere, and be loaded from there – think of it as plugging them into your application.

To achieve all this, following Henrik’s advice, you need a class implementing IAssemblyResolver, for example, your own class derived from System.Web.Http.Dispatcher.DefaultAssembliesResolver:

So effectively you are asking the framework to get its default assemblies (located under web app’s /bin/ folder), and merge your custom assembly in there as well.

There is a kicker though. It only works with the latest Web API source (nighly Nuget packages or build from Codeplex), not with RC.

Making this work with ASP.NET Web API RC

Why? The issue here is that the class from which we inherited from, DefaultAssembliesResolver, is internal in RC, and was only made public after the RC was released.

However, there is no reason why you wouldn’t write your own class implementing IAssembliesResolver. Let’s modify the above code to get there:

So this looks very similar to the bit above. Instead of inheriting from DefaultAssembliesResolver, we implement IAssembliesResolver directly, and read the assemblies from AppDomain ourselves (that’s what DefaultAssembliesResolver does), and merge in a List with our custom assembly.

Now we are ready to plug this in, and as expected this has to be done in Global.asax, or any other class you have to manipulate GlobalConfiguration.

Trying it out

Now assuming that:
ValuesController is located under main web application project
ExternalController is located in C:libscontrollersControllersLibrary.dll

You can see that it’s easy to navigate to both of them:


It is really easy to separate your controllers from your web application. While this might seem like an overkill in small projects, in large enterprise scale applications, it is an absolute lifesaver. I hope I don’t have to convince anyone who much it helps maintainability, testability and mess/noise reduction.


  • Pingback: Dew Drop – June 21, 2012 (#1,349) | Alvin Ashcraft's Morning Dew()

  • Pingback: | TechBlog()

  • Pingback: The Morning Brew - Chris Alcock » The Morning Brew #1131()

  • http:/// Alexsandro (@alexsandro_xpt)

    Did you have same sample using MEF?


  • Victor

    What is needed for a controller in a class library besides inheriting from ApiController class?

    I created the following web api controller as a class library

    public class ExternalController : ApiController
    // GET api/values
    public IEnumerable Get()
    return new string[] { “value1 from library”, “value2 from library” };

    // GET api/values/5
    public string Get(int id)
    return “value from libary”;

    but it is not working I am getting the following error:

    No HTTP resource was found that matches the request URI ‘http://localhost:58452/api/external’.No type was found that matches the controller named ‘external’.

    I created a AssembliesResolver class as you described in your article and I added
    GlobalConfiguration.Configuration.Services.Replace(typeof(IAssembliesResolver), new AssembliesResolver());

    in the global.asax file

    Thanks in advance for your help


    • Jeff L8

      I am getting the same error as you, did you ever get this working?

      No HTTP resource was found that matches the request URI ‘http://localhost:2524/api/external’.

      No type was found that matches the controller named ‘external’.

      Is there a way to do this with an assembly added as a reference in your Web API project or do you have to add an Assembly.LoadFrom(fileLocation);?

    • dave_gardner

      I hit the same problem. The fix is to create an implementation of IAssembliesResolver rather than inheriting from DefaultAssembliesResolver.

  • Victor

    I got it to work. it seems that I needed the implementation for ASP.NET Web API RC instead. It is strange because recently I upgraded my solution to the latest MVC 4 (RTM)

  • Daniel Silva

    You said that “Controllers don’t really need Global.asax or anything else the web application provides”. But what about Dependency Injection and other stuff like this that needs to be initialized for the API?

    • Filip W

      The typical IoC setup in any application is to have a single composition root – and have all dependencies defined there, and then the IoC container simply propagates them through all the layers of your application, regardless of in which DLL the dependencies are needed. See more about this here –

      You definitely do not have to set up dependency injection into the controllers in the same project/DLL as the controllers.

  • Carl Clark

    Thanks for this post it helped me get my dynamic Controller loading working. I used you RTM code version but had to revise it to return baseAssemblies to get it to work.

    Thanks again

  • Michael Hand

    Thank you!

    BTW line 7 in the first listing should be assemblies.Add(controllersAssembly);

  • Tyson Nero

    I would also check out Autofac WebApiIntegration for resolving dependencies:

  • Algis

    Hi, could someone share working sample of this supposedly simple stuff, but I can’t get it working…

  • Algis

    Sorry, got it working, but had to use “RC” way as well…

  • Jon Pawley

    Filip, many thanks for this blog post. I ended up not needing to use what you had described, as I have wired up Autofac as my WebAPI “dependency resolver”, but this great blog post pointed me in the right direction. Awesome work.

  • Mike Cattle

    Great solution, but could you not also use plain ol’ inheritance to do the trick? As in, write “empty” controller classes in your Web API assembly that inherit from the controller classes in the other assembly?

  • Brandon D’Imperio

    This doesn’t appear to be necessary when using Microsoft.AspNet.WebApi.Core 5.1.2

  • Srinivas

    I got it working. But when i try to use OData [IQueriable] in the external / internal controller it throws error [An item with the same key has already been added.]. Do you know how to handle this?

    Thanks in Advance

  • PrabalM

    We are using MVC4 and IIS8. Looks like it is just working without doing anything, I have implemented new modules API controller in a dll and drop that dll in the bin folder of WebAPI app. Thats it. Not sure why it is working and what is the mechanics behind. It would be great if someone can explain!!!

  • Radosław Łoboda

    I found a simpler solution online for current (Sep 2015) version of WebAPI. Since we are ensuring our library is actually loaded, all we need to do is call any method from that library.
    There comes one more issue – route attribute mapping and routing in general which is limited to some scope (namespace?). So you have to move this setup part inside external library:

    using System.Web.Http;
    namespace MyLib
    public static class MyLibConfig
    public static void Register(HttpConfiguration config)
    name: “DefaultApi”,
    routeTemplate: “{controller}”
    } } }

    And then call it from host application (owin self-host here):

    using Owin;
    using System.Web.Http;
    using MyLib;
    namespace MyApp
    public class Startup
    public void Configuration(IAppBuilder app)
    var webApiConfiguration = ConfigureWebApi();
    private HttpConfiguration ConfigureWebApi()
    var config = new HttpConfiguration();
    return config;
    } } }

    Works like a charm.

  • Matt Reamy

    I know this is a really old article (in internet time, anyway), but this helped me solve the problem of getting external-library-controllers loaded into my WebAPI project. Thank you!
    This, as written, doesn’t allow for attribute routing within the external libraries. The idea that Radosław Łoboda posted indicates some prior knowledge of the services (and would require a rebuild when a new library is introduced). At least that’s how I read it.

    I’m using MEF to compose the application. The idea is to build a Web Service Host to which one can add any number of libraries containing services. I wondered if you have extended this example to use Attribute Routing in the external libraries. (I didn’t find a search feature on your blog, so if this is asked and answered, I’d appreciate a link).
    Thanks again for this. This gets me farther than I had been before when trying something like this.

  • OnoSendai

    Just a quick ‘thank you’ – information about IAssembliesResolver was crucial to solve an issue on my add-on engine.

  • Rajasekaram Rahulan

    What is the easiest way to debug the class library controller code?