aspnet / Mvc

[Archived] ASP.NET Core MVC is a model view controller framework for building dynamic web sites with clean separation of concerns, including the merged MVC, Web API, and Web Pages w/ Razor. Project moved to https://github.com/aspnet/AspNetCore
Apache License 2.0
5.62k stars 2.14k forks source link

Plugin architecture at runtime - keep the application running while adding functionality #5573

Closed ngoov closed 7 years ago

ngoov commented 7 years ago

I'm using the AssemblyLoaderContext in ASP.NET Core 1.1 to load a dll in my plugin folder in my MVC main application with the 'LoadAssemblyFromPath' function. However, I'd like to the attribute routing of my plugin dll's controller to work in my main application. For this I should be able to clear and rebuild the MVC routing. How is this possible to do? It used to be doable in MVC 4-5 using GlobalConfiguration, but as I read on some blogs, it was not a best practice and so the GlobalConfiguration is removed from ASP.NET Core.

So, how can I rebuild the MVC routes, not from the startup class, because I don't want to restart my web application? I'm aiming for an experience like Wordpress and Drupal, where you upload the dll in this case to the server and in the UI, press activate to load this plugin.

pranavkm commented 7 years ago

We added a feature to support reloading ActionDescriptors in 1.2 (our dev branch) to support RazorPages. You should be use most of the code \ pattern we have in a 1.1 application to make this work:

I'm aiming for an experience like Wordpress and Drupal

Have you considered using a CMS for this? For instance https://github.com/OrchardCMS/Orchard2?

ngoov commented 7 years ago

@pranavkm I forgot to mention that I'm not using Razor. I'm making an API project to which endpoints can be added at runtime using a plugin architecture. For example, to the 'Main Application' that is running on a server, I want to add a project (by compiling it to a dll) that contains a controller like:

namespace MainApplication.Plugin.PluginTest.Controllers{
    [Route("api/[controller]")]
    public class TestController : Controller{
        public IActionResult Get(){
              return Ok(new {value = "Ok from Test!"});
        }
    }
}

Then in a 'PluginManager' like class, I would install the dll using the Assembly.LoadAssemblyFromPath("path/to/dll") and here I would need some 'magic' to add this Route attribute to the MVC route, so rebuild the routes.

Is this even possible at runtime or should this be avoided?

Have you considered using a CMS for this? For instance https://github.com/OrchardCMS/Orchard2?

I don't want the bloat of a CMS, just giving those 2 as an example of what result is expected. Because PHP is not being compiled, the application does not have to be restarted. However I'm hoping the same functionality is possible with the new ASP.NET Core.

pranavkm commented 7 years ago

@pranavkm I forgot to mention that I'm not using Razor.

The changes I pointed to really don't have anything to do with Razor. I just pointed you to RazorPages as demonstration of what the pattern is for the route table to be reconstructed. You can do something similar to what we do in RazorPages in your PluginManager to reload ActionDescriptor instances which would in turn cause the routes to be reconstructed.

andrew-vdb commented 7 years ago

@pranavkm During RC, we can publish with controller.cs instead of having dll On RTM, its all dll

Can we have an option during publish, publish as .cs instead of .dll?

pranavkm commented 7 years ago

@andrew-vandenbrink dynamic compilation of the application's sources (.cs files) is no longer supported.

andrew-vdb commented 7 years ago

@pranavkm thats too bad

Eilon commented 7 years ago

cc @danroth27 @sebastienros due to the relationship to modules, but closing this issue as no further action is required here.

danroth27 commented 7 years ago

@nfdevil Orchard2 is actually more than a CMS. It's actually a well factored application framework. You can leverage the extensions support in Orchard2 without pulling in all the CMS functionality, so it's definitely worth a look. For example on how simple it can be see: https://github.com/OrchardCMS/Orchard2/blob/master/src/Orchard.Mvc.Web/Startup.cs