应用启动后加载的DLL能否使用控制器与视图?登录后按权限加载场景
动态加载登录后权限对应DLL的控制器与视图方案
可以实现,但需要分别处理控制器的动态发现和视图的路径查找逻辑,以下是具体实现步骤:
控制器动态加载与路由注册
ASP.NET Core默认在启动阶段扫描程序集识别控制器,所以要让登录后加载的DLL中的控制器被路由识别,需要手动更新应用程序部件:
- 用户完成权限验证后,加载目标程序集:
// 替换为实际的DLL路径 var targetAssembly = Assembly.LoadFrom(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "PermissionBased.dll")); - 将加载的程序集添加到
ApplicationPartManager,让框架识别其中的控制器:var part = new AssemblyPart(targetAssembly); var partManager = app.ApplicationServices.GetRequiredService<ApplicationPartManager>(); partManager.ApplicationParts.Add(part); - 刷新路由端点:需要触发框架重新发现控制器并更新路由,可以通过重新构建
EndpointDataSource实现,核心是确保新加载的控制器路由被注册到应用中。
视图的加载与访问
动态DLL中的视图如果是内嵌资源(推荐打包方式),需要配置视图引擎能找到这些资源:
- 注册内嵌文件提供者,让应用能访问DLL中的内嵌视图:
// 第二个参数是视图所在的命名空间(通常是项目名.Views) var embeddedProvider = new EmbeddedFileProvider(targetAssembly, "PermissionBased.Views"); app.UseStaticFiles(new StaticFileOptions { FileProvider = embeddedProvider }); - 自定义视图位置扩展器,让Razor视图引擎能定位到动态DLL中的视图:
public class DynamicViewLocationExpander : IViewLocationExpander { public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations) { // 添加动态视图的位置格式,根据实际结构调整 var dynamicLocations = new List<string> { "/Views/{1}/{0}.cshtml", "/Views/Shared/{0}.cshtml" }; return viewLocations.Concat(dynamicLocations); } public void PopulateValues(ViewLocationExpanderContext context) { // 可添加自定义值用于视图定位 } } - 在服务配置中注册这个扩展器:
services.Configure<RazorViewEngineOptions>(options => { options.ViewLocationExpanders.Add(new DynamicViewLocationExpander()); });
关键注意事项
- 安全校验:加载DLL前必须验证其合法性,比如校验哈希值或数字签名,防止加载恶意组件。
- 依赖兼容:确保动态加载的DLL与主应用的.NET版本、第三方依赖版本一致,避免运行时冲突。
- 路由冲突:动态控制器建议使用独特的路由前缀(比如
[Route("Permission/{controller}/{action}")]),避免和现有控制器路由冲突。 - 内嵌视图配置:在DLL项目中,要将视图文件的
Build Action设置为Embedded Resource,否则无法通过内嵌文件提供者访问。
内容的提问来源于stack exchange,提问作者Jorge
相关产品推荐
相关产品推荐

