首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从同一程序集的不同版本加载控制器

如何从同一程序集的不同版本加载控制器
EN

Stack Overflow用户
提问于 2020-02-05 07:21:29
回答 1查看 292关注 0票数 2

我正试图解决以下问题,但我不太清楚该如何解决:

我正在构建一个具有不同API/控制器的web服务器,这些API/控制器是在启动时从..dll Files加载的。它将在linux容器中运行,并作为一个ASP.NETWeb应用程序& .net Core2.1实现。

通过执行以下操作,加载包含控制器的程序集运行良好:

代码语言:javascript
复制
public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    services.AddMvc().AddApplicationPart(AssemblyLoadContext.Default.LoadFromAssemblyPath("/PATH/APIPlugin.dll"));
}

此应用程序必须具有版本化的REST-API,这意味着:我需要在不同版本中多次加载相同的程序集。然后我需要在不同版本之间进行某种路由。例如:

  • /api/data/latest/
  • /api/data/v1/

我不能使用AssemblyLoadContext.Default.LoadFromAssemblyPath加载同一程序集的多个版本。我还试图从程序集中获取控制器,并创建一个如下所示的实例:

代码语言:javascript
复制
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));

这不例外,但最终不起作用。但是我对ASP.Net非常陌生,所以这很可能是胡说八道,我必须找到一个解决方案来在不同的版本之间穿行,即使它会像这样工作。

我的问题是:怎样才能达到这一要求?从“同一”程序集加载多个控制器是上帝的想法/可能吗?如果是,如何做到这一点?或者,如果有一个控制器从程序集中执行所有路由和加载自定义实现,是否是一个更好的解决方案。以便控制器在版本和api-方法之间进行路由?

EN

回答 1

Stack Overflow用户

发布于 2020-02-05 12:02:24

当我四处修修补补的时候,我找到了一个建议:

代码语言:javascript
复制
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());
            }
        }
    }
}

在启动阶段:

代码语言:javascript
复制
public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddMvc().ConfigureApplicationPartManager(m => 
  m.FeatureProviders.Add(new ControllerPluginProvider()));
}

这将导致在加载相同程序集时出现以下错误,因此加载具有相同名称的Controller时:具有相同名称“Get”的属性路由必须具有相同的模板

我修复了它,并使用版本库添加了版本控制:https://github.com/microsoft/aspnet-api-versioning

代码语言:javascript
复制
[ApiVersion("2.0")]
[ApiController]
[Route("api/v{version:apiVersion}/MyController")]
public class MyControllerController : ControllerBase
{
}

现在,唯一缺少的步骤是将/latest/ path路由到给定类型的最新控制器。我还没有找到解决办法,但这应该是可行的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60070761

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档