Is it possible to reference ASP.NET Core Razor views from separate assembly at runtime?
I know how to load controllers dynamically using IActionDescriptorChangeProvider
but cannot find a way as for views.
I'd like to create a simple plugin system and manage plugins without restart app.
相关问题
- Can I use MvcJsonOptions configured during Startup
- Singleton with AsyncLocal vs Scope Service
- gRPC client do not dispose Channel
- Unable to resolve service for type 'Microsoft.
- Which encryption algorithm do we use in Asp.net 5
相关文章
- EF Core 'another instance is already being tra
- Re-target .NET Core to net471, net 472
- How to replace Middleware in integration tests pro
- Why CsvHelper not reading from MemoryStream?
- Breakpoint in ASP.NET MVC Razor view will not be h
- How to define function that returns html in asp.ne
- MVC 3 Razor - Trigger validation from controller
- Should I use xUnitPublisher or xUnitBuilder after
I am creating a dynamic and fully modular (plugin-based) application in which the user can drop a plugin assembly at run time in a file watched directory to add controllers and compiled views.
I ran in the same issues than you. At first, both controllers and views were not being 'detected' by MVC, even though I add correctly added the assemblies through the ApplicationPartManager service.
I solved the controllers issue which, as you said, can be handled with the IActionDescriptorChangeProvider.
For the views issue, though, it seemed there was no similar mechanism built-in. I crawled google for hours, found your post (and many others), but none were answered. I almost gave up. Almost.
I started crawling the ASP.NET Core sources and implemented all service I thought was related to finding the compiled views. A good part of my evening was gone pulling my hairs, and then... EUREKA.
I found that the service responsible for supplying those compiled views was the default IViewCompiler (aka DefaultViewCompiler), which was in turn provided by the IViewCompilerProvider (aka DefaultViewCompilerProvider).
You actually need to implement both those to get it working as expected.
The IViewCompilerProvider:
The IViewCompiler:
Now, you need to find the existing IViewCompilerProvider descriptor, and replace it with your own, as follows:
Then, upon loading a compiled view plugin assembly, just make the following call:
Upon unloading a compiled view plugin assembly, make that call:
That will cancel and get rid of the IChangeToken that we have associated with the compiled views loaded with our plugin assembly. This is very important if you intend to load, unload then reload a specific plugin assembly at runtime, because otherwise MVC will keep track of it, possibly forbidding the unloading of your AssemblyLoadContext, and will throw error upon compilation because of model types mismatch (model x from assembly z loaded at time T is considered different than model x from assembly z loaded at time T+1)
Hope that helps ;)