Search code examples
asp.net-mvcpluginsmodule.net-assemblyapplication-pool

ASP.Net MVC: How to dynamically load assemblies (controllers) without an AppPool restart/recycle


I'm trying to write a module/plugin system for a website I'm working on. The overall goals are:

  1. That the main website does not have to be recompiled every time a new plugin is added.
  2. To be able to dump DLL's and CSHTML files into a set of folders that would basically add a set of routes, controller(s), and any other assemblies that the module depends on (Entity Framework, etc).
  3. To avoid marking plugin files as "embedded resources" -- especially views.
  4. To be able to add and remove these modules/plugins WITHOUT having to restart/recycle the IIS app pool or unload the app domain.

I got #1-3 working by following the example of Umbraco. Basically, I marked a method with the PreApplicationStartMethod attribute, and in it I shadow copy DLLs around, and use a custom ViewEngine to locate the module's CSHTML files. When my website first starts up, my module's controllers and views are working, and assemblies are loaded: Hooray!

However, when it came time to try part #4, I am getting this error when calling BuildManager.AddReferencedAssembly():

This method can only be called during the application's pre-start initialization phase. Use PreApplicationStartMethodAttribute to declare a method that will be invoked in that phase

It's been a very frustrating process so far, and my gut tells me that this error signifies a dead end. Is this the case, or is there a clever workaround?


Solution

  • "To be able to add and remove these modules/plugins WITHOUT having to restart/recycle the IIS app pool or unload the app domain."

    It turns out that this you cannot unload an assembly from an app domain.

    How to unload an assembly from the primary AppDomain?