我需要创建一个可以扩展的ASP.NET核心2应用程序。
扩展,是一个引用主程序集并可以扩展它的项目,它可以添加新的控制器、模型(带有EF迁移)、视图、剃须刀页面等。
由于扩展需要使用主应用程序基类,如基本控制器、基本模型或视图/页面布局,主应用程序不能引用模块项目(避免循环引用)。
我不知道如何实现这一点,但想法是安装一个主项目,可以添加新功能简单地放入模块DLL (或通过在线市场的主应用程序,即下载DLL)。
在我的研究中,我发现了应用部件,但我这里的问题是,我需要在启动类中指定部件组装,我需要安装模块的容量,而不需要对代码进行任何更改。
有些模块也需要扩展,例如会计模块,需要与银行连接,并且它有一个接口,定义了与银行合作的方法,例如:
public interface IBankingOperation
{
public async void PayInvoiceAsync(Invoice invoice);
// More methods...
}然后,不同的项目可以为银行的组装提供参考,并为不同的银行提供实施。
在主应用程序中,这个模块可以像其他模块一样安装,但是检查基本模块是必要的,例如,我可以像安装其他模块一样安装Santander模块,但只有在安装了银行模块(模块依赖)时才能安装。
总结,我需要创建一个模块化的ASP.NET核心2应用程序,但是主程序集不能引用模块,模块必须引用主程序集。这些模块可以包含控制器、模型、视图、页面等。
发布于 2018-10-09 19:33:21
在主web应用程序中,您将调用一个类,它在内存中加载扩展。
ModuleManager.LoadModules(Path.Combine(_env.ContentRootPath, "Modules"));
这是加载模块函数。
public static void LoadModules(string modulesFolder)
{
var appsFolders = new DirectoryInfo(modulesFolder).GetDirectories();
foreach (var appFolder in appsFolders)
{
var binFolder = new DirectoryInfo(Path.Combine(appFolder.FullName, "bin"));
if (!binFolder.Exists)
{
continue;
}
var assemblies = AssemblyProvider.GetAssemblies(binFolder.FullName);
foreach (var assembly in assemblies)
{
var iModuleClass = assembly.GetTypes().FirstOrDefault(type => type.GetInterfaces().Contains(typeof(IModule))
&& type.GetConstructor(Type.EmptyTypes) != null);
if (iModuleClass != null)
{
var module = Activator.CreateInstance(iModuleClass) as IModule;
module.ModuleFolder = appFolder;
Modules.Add(module);
Assemblies.Add(assembly);
break;
}
}
}
}然后,您应该有一个由每个模块实现的接口,实现该接口的类应该完成注册服务和数据库模型的工作,以及所有需要的人员,您将按以下方式加载它们
public static IEnumerable<IExtensionRegister> GetModuleRegistrars()
{
lock (Modules)
{
return Modules.Select(item => item.Registrar).Where(item=>item!=null).ToList();
}
}https://stackoverflow.com/questions/52486566
复制相似问题