c# - 使用 net core 3 MVC 在运行时加载程序集和视图
问题描述
你好吗?我来找你帮忙。
我告诉你我有一个用 asp net core 3 开发的 MVC web 应用程序。
我有一个基本的 MVC Web 应用程序,它包含区域并处理用户管理应用程序、权限等的基本功能。
现在我想为特定功能添加一个新区域,在这种情况下是客户管理。我不想要的是直接向基础项目添加一个区域。
我想要的是动态加载 dll 文件和视图,以保持功能分开,如果一个失败,另一个继续工作。
实现加载 DLL 的功能,这确实有效,因为我使用 web api 对其进行了测试。
但是我找不到加载区域视图的方法,我用 MVC 5 Net Framework 做了一些,尝试传递功能,显然类不一样。你可以帮我解决这个问题。
非常感谢您提前。
代码下方:
插件扩展.cs
public static class PluginExtensions
{
public static IMvcBuilder AddExtensions(this IMvcBuilder mvc)
{
var serviceProvider = mvc.Services.BuildServiceProvider();
var configuration = serviceProvider.GetService<IConfiguration>();
var hostingEnvironment = serviceProvider.GetService<IWebHostEnvironment>();
var logger = serviceProvider.GetService<ILoggerFactory>().CreateLogger<Startup>();
List<string> extensionDirectories = EnumerateExtensionDirectories(serviceProvider).ToList();
List<string> searchPatternList = new List<string>
{
"*Extension.Mvc*.dll"
};
mvc.ConfigureApplicationPartManager(apm =>
{
List<string> extensionAssemblies = new List<string>();
foreach (var extensionDirectory in extensionDirectories)
{
for (int i = 0; i < searchPatternList.Count; i++)
{
List<string> tempList = EnumerateExtensionAssemblies(extensionDirectory, searchPatternList[i]).ToList();
if (tempList != null && tempList.Count > 0)
extensionAssemblies.AddRange(tempList);
}//for(int i=0;i< searchPatternList.Count; i++)
}//foreach (var extensionDirectory in extensionDirectories)
foreach (var extensionAssembly in extensionAssemblies)
{
if (TryLoadExtensionAssembly(serviceProvider, extensionAssembly, out var assembly))
{
//logger.Log(AbortAction.Layer.Infrastructure().Meta(new { extensionAssembly = new { extensionAssembly.FullName } }));
apm.ApplicationParts.Add(new AssemblyPart(assembly));
}// if (TryLoadExtensionAssembly(serviceProvider, extensionAssembly, out var assembly))
}// foreach (var extensionAssembly in extensionAssemblies)
});
if (hostingEnvironment.IsProduction() || hostingEnvironment.IsDevelopment())
{
ConfigureAssemblyResolve(serviceProvider);
}
return mvc;
}
private static IEnumerable<string> EnumerateExtensionAssemblies(IServiceProvider serviceProvider)
{
var configuration = serviceProvider.GetService<IConfiguration>();
var hostingEnvironment = serviceProvider.GetService<IWebHostEnvironment>();
var extRootPath = Path.Combine(hostingEnvironment.ContentRootPath, configuration["Extensibility:Ext"]);
if (!Directory.Exists(extRootPath)) return new List<string>();
return Directory.EnumerateFiles(extRootPath, "*Extension.Mvc*.dll");
}
private static IEnumerable<string> EnumerateExtensionAssemblies(string assembliesDirectory, string searchPattern)
{
if (!Directory.Exists(assembliesDirectory)) return new List<string>();
return Directory.EnumerateFiles(assembliesDirectory, searchPattern);
}
private static IEnumerable<string> EnumerateExtensionDirectories(IServiceProvider serviceProvider)
{
var configuration = serviceProvider.GetService<IConfiguration>();
var hostingEnvironment = serviceProvider.GetService<IWebHostEnvironment>();
var extRootPath = Path.Combine(hostingEnvironment.ContentRootPath, configuration["Extensibility:Ext"]);
if (!Directory.Exists(extRootPath)) return new List<string>();
return Directory.EnumerateDirectories(extRootPath);
}
private static bool TryLoadExtensionAssembly(IServiceProvider serviceProvider, string extensionAssembly, out Assembly assembly)
{
//extensionAssembly
try
{
if (File.Exists(extensionAssembly))
{
assembly = Assembly.LoadFile(extensionAssembly);
return true;
}
}
catch (Exception ex)
{
// logger.Log(Abstraction.Layer.Infrastructure().Routine(nameof(TryLoadExtensionAssembly)).Faulted(), ex);
}
assembly = default;
return false;
}
private static void ConfigureAssemblyResolve(IServiceProvider serviceProvider)
{
var configuration = serviceProvider.GetService<IConfiguration>();
var hostingEnvironment = serviceProvider.GetService<IWebHostEnvironment>();
var logger = serviceProvider.GetService<ILoggerFactory>().CreateLogger<Startup>();
List<string> extensionDirectories = EnumerateExtensionDirectories(serviceProvider).ToList();
List<string> extensionAssemblies = new List<string>();
List<string> searchPatternList = new List<string>
{
"*Extension.Entities*.dll",
"*Extension.Libs*.dll",
"*Extension.Data*.dll",
"*Extension.Application*.dll",
"*Extension.UtilsConnectors*.dll"
};
foreach (var extensionDirectory in extensionDirectories)
{
for (int i = 0; i < searchPatternList.Count; i++)
{
List<string> assembliesReferenceList = EnumerateExtensionAssemblies(extensionDirectory, searchPatternList[i]).ToList();
if (assembliesReferenceList != null && assembliesReferenceList.Count > 0)
foreach (var assemblyReference in assembliesReferenceList)
{
AppDomain.CurrentDomain.AssemblyResolve += (sender, e) =>
{
return
File.Exists(assemblyReference)
? Assembly.LoadFile(assemblyReference)
: null;
};// AppDomain.CurrentDomain.AssemblyResolve += (sender, e) =>
}//foreach (var assemblyReference in assembliesReferenceList)
}// for (int i = 0; i < searchPatternList.Count; i++)
}//foreach (var extensionDirectory in extensionDirectories)
}
}
public static class HostingEnvironmentExtensions
{
public static bool IsDevelopmentExt(this IWebHostEnvironment hostingEnvironment)
{
return hostingEnvironment.IsEnvironment("DevelopmentExt");
}
}
启动.cs
public void ConfigureServices(IServiceCollection services)
{
...
services.AddMvc(options =>
{
options.Filters.Add(new SessionExpireAttribute());
}).AddExtensions();
...
}
正如你所看到的,我加载了 dll 文件,这是可行的。
后来我将文件(dll和视图(html))复制到我的基础项目的区域文件夹中
我所在地区的 DLL
终于看到我所在的地区了
结果
最后在项目类型扩展的startup.cs文件中。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
app.UseEndpoints(endpoints =>
{
endpoints.MapAreaControllerRoute(
name: "AreaMyArea",
areaName: "MyArea",
pattern: "MyArea/{controller=MYHome}/{action=Index}/{id?}");
endpoints.MapControllerRoute(
name: "defaultMA",
pattern: "{controller=MyExtHome}/{action=Index}/{id?}");
});
}
抱歉,此信息的广泛性。你能帮助我吗?。我尽量说清楚。非常感谢你,祝你有美好的一天。
解决方案
推荐阅读
- ms-word - 如何运行邮件合并但保留某些合并字段“未处理”,即不要有条件地删除某些合并字段
- python - Python检查切片后行是否为空
- javascript - PouchDB IE11 使用 file://
- javascript - Thymeleaf 预处理表达式不能附加括号
- css - 动态更新 Ext.grid.ActionColumn 中单元格的光标样式
- ibm-doors - 将 IF 语句添加到 DXL 脚本以检查对象类型?
- swift - 我是否必须为 MacOS 以下的 el capitan 制作一个 swift 和 xcode 较低的新项目?
- ios - 如何使用组合框架 NSObject.KeyValueObservingPublisher?
- swift - Swift 中有没有办法部分匹配泛型?
- python - 通过 GUI 用户交互和行命令触发 tkinter 回调