C# 如何从同一程序集的不同版本加载控制器
我正在尝试解决以下问题,但我不确定如何解决: 我正在构建一个web服务器,它具有不同的API/控制器,这些API/控制器在启动时从.dll文件加载。它将在linux docker容器中运行,并作为ASP-NET Web应用程序和.NET Core 2.1实现 通过执行以下操作,加载包含控制器的程序集工作正常:C# 如何从同一程序集的不同版本加载控制器,c#,asp.net,.net,.net-core,C#,Asp.net,.net,.net Core,我正在尝试解决以下问题,但我不确定如何解决: 我正在构建一个web服务器,它具有不同的API/控制器,这些API/控制器在启动时从.dll文件加载。它将在linux docker容器中运行,并作为ASP-NET Web应用程序和.NET Core 2.1实现 通过执行以下操作,加载包含控制器的程序集工作正常: public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatib
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddMvc().AddApplicationPart(AssemblyLoadContext.Default.LoadFromAssemblyPath("/PATH/APIPlugin.dll"));
}
var controllerAssembly = AssemblyLoadContext.Default.LoadFromAssemblyPath("/PATH/APIPlugin.dll");
var pluginType = controllerAssembly ExportedTypes.First<Type>();
var pluginInstance = (ControllerBase)Activator.CreateInstance(pluginType);
services.Add(new ServiceDescriptor(pluginType, pluginInstance));
此应用程序必须具有版本化的RESTAPI,这意味着:我需要在不同版本中多次加载同一程序集。然后我需要在版本之间进行某种路由。
例如:
- /api/数据/最新/
- /api/data/v1/
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddMvc().AddApplicationPart(AssemblyLoadContext.Default.LoadFromAssemblyPath("/PATH/APIPlugin.dll"));
}
var controllerAssembly = AssemblyLoadContext.Default.LoadFromAssemblyPath("/PATH/APIPlugin.dll");
var pluginType = controllerAssembly ExportedTypes.First<Type>();
var pluginInstance = (ControllerBase)Activator.CreateInstance(pluginType);
services.Add(new ServiceDescriptor(pluginType, pluginInstance));
var controllerAssembly=AssemblyLoadContext.Default.LoadFromAssemblyPath(“/PATH/APIPlugin.dll”);
var pluginType=controllerAssembly ExportedTypes.First();
var pluginInstance=(ControllerBase)Activator.CreateInstance(pluginType);
添加(新的ServiceDescriptor(pluginType,pluginInstance));
这没有例外,但最终不起作用。但是我对ASP.Net还很陌生,所以这很可能是无稽之谈,我必须找到一个解决方案在不同版本之间进行路由,即使它是这样工作的
我的问题:
如何达到这一要求?
从“同一”程序集中加载多个控制器是否可行?如果是,如何实现这一目标?
或者,让一个控制器执行所有路由并从程序集加载一些自定义实现是更好的解决方案。这样控制器就可以在版本和api方法之间进行路由了?我在修补时找到了一个结果:
public class ControllerPluginProvider : IApplicationFeatureProvider<ControllerFeature>
{
public void PopulateFeature(IEnumerable<ApplicationPart> parts, ControllerFeature feature)
{
var basePath = AppContext.BaseDirectory;
var pluginPath = Path.Combine(basePath, "plugins");
foreach (var file in Directory.GetFiles(pluginPath, "*.dll")){
var assembly = Assembly.LoadFile(file);
var controllers = assembly.GetExportedTypes().Where(t => typeof(ControllerBase).IsAssignableFrom(t));
foreach (var candidate in controllers)
{
feature.Controllers.Add(candidate.GetTypeInfo());
}
}
}
}
当加载相同程序集时,这会导致以下错误,因此加载了具有相同名称的控制器:具有相同名称“Get”的属性路由必须具有相同的模板
我可以修复它,还可以使用版本控制库添加版本控制:
现在缺少的唯一一步是将/latest/path路由到给定类型的最新控制器。我还没有找到解决方案,但这应该是可行的。我在修补时找到了一个结果:
public class ControllerPluginProvider : IApplicationFeatureProvider<ControllerFeature>
{
public void PopulateFeature(IEnumerable<ApplicationPart> parts, ControllerFeature feature)
{
var basePath = AppContext.BaseDirectory;
var pluginPath = Path.Combine(basePath, "plugins");
foreach (var file in Directory.GetFiles(pluginPath, "*.dll")){
var assembly = Assembly.LoadFile(file);
var controllers = assembly.GetExportedTypes().Where(t => typeof(ControllerBase).IsAssignableFrom(t));
foreach (var candidate in controllers)
{
feature.Controllers.Add(candidate.GetTypeInfo());
}
}
}
}
当加载相同程序集时,这会导致以下错误,因此加载了具有相同名称的控制器:具有相同名称“Get”的属性路由必须具有相同的模板
我可以修复它,还可以使用版本控制库添加版本控制:
现在缺少的唯一一步是将/latest/path路由到给定类型的最新控制器。我还没有找到解决办法,但这应该是可行的