简体   繁体   中英

ASP.NET MVC - Dynamically load views from external DLL

I have a use case in an application I'm writing where I have logic in an external DLL that is loaded dynamically. Now I need to add the ability to display shared views inside the ASP.NET MVC view that resides in the external DLL.

What I've done so far is to add the following in my ConfigureServices method:

UriBuilder uri = new UriBuilder(Assembly.GetEntryAssembly().CodeBase);
string fullPath = Uri.UnescapeDataString(uri.Path);
var mainDirectory = Path.GetDirectoryName(fullPath);
var assemblyFilePath = Path.Combine(mainDirectory, "MyLogic.dll");

var asmStream = File.OpenRead(assemblyFilePath);
var assembly = AssemblyLoadContext.Default.LoadFromStream(asmStream);

var part = new AssemblyPart(assembly);
services.AddControllersWithViews().ConfigureApplicationPartManager(apm => apm.ApplicationParts.Add(part));

This works fine as long as the DLL is added as a reference to the project. If I remove the reference then I'm getting an error in my application when I try to load the partial view:

InvalidOperationException: The partial view 'MyView' was not found. The following locations were searched: /Views/Consent/MyView.cshtml /Views/Shared/MyView.cshtml

What I tried doing is to list all known view of the application using the following code:

var feature = new ViewsFeature();
applicationPartManager.PopulateFeature(feature);
var views = feature.ViewDescriptors.Select(x => x.RelativePath).ToList();

What I see is that when I add the DLL as a reference in the project I see MyView.cshtml in the list, and if not then I don't see it - and the above error makes sense.

But my use case dictates that the loaded DLL is not referenced. Is there a way to add the views from it when it's not a reference?

Mystery solved... instead of ConfigureApplicationPartManager need to use AddApplicationPart like this:

UriBuilder uri = new UriBuilder(Assembly.GetEntryAssembly().CodeBase);
string fullPath = Uri.UnescapeDataString(uri.Path);
var mainDirectory = Path.GetDirectoryName(fullPath);
var assemblyFilePath = Path.Combine(mainDirectory, "Risco.Auth.Demo.Bridge.dll");

var asmStream = File.OpenRead(assemblyFilePath);
var assembly = AssemblyLoadContext.Default.LoadFromStream(asmStream);

services.AddControllersWithViews().AddApplicationPart(assembly);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM