Asp.net web api Web API 2是否可以通过编程方式加载路由/控制器?

Asp.net web api Web API 2是否可以通过编程方式加载路由/控制器?,asp.net-web-api,asp.net-web-api-routing,programmatically-created,Asp.net Web Api,Asp.net Web Api Routing,Programmatically Created,我目前正在开发一个使用WCF实现RESTAPI的企业web应用程序。它利用VirtualPathProvider捕获对*.svc文件(实际上不存在)的请求,然后动态构建它们以动态加载相关的WCF服务。这允许系统具有“模块”,可以在运行时添加到应用程序中,而不会影响web服务器或任何使用它的人 我想知道的是,WebAPI2在概念上是否也可以做到这一点。我一直在做一些研究,但看起来路由只能在启动时配置。。。我所希望的是一种处理不存在的路由的方法,基本上使用请求中的控制器名称来查找和加载关联的程序集(

我目前正在开发一个使用WCF实现RESTAPI的企业web应用程序。它利用VirtualPathProvider捕获对*.svc文件(实际上不存在)的请求,然后动态构建它们以动态加载相关的WCF服务。这允许系统具有“模块”,可以在运行时添加到应用程序中,而不会影响web服务器或任何使用它的人

我想知道的是,WebAPI2在概念上是否也可以做到这一点。我一直在做一些研究,但看起来路由只能在启动时配置。。。我所希望的是一种处理不存在的路由的方法,基本上使用请求中的控制器名称来查找和加载关联的程序集(如果存在),同时以编程方式向其添加新路由


我刚刚开始使用WebAPI2,所以我希望能有一些更有经验的用户加入进来。基本上,我的团队有兴趣切换到Web API 2,以减少我们在WCF中遇到的开销和复杂性,但这一特殊要求可能会破坏交易。

好的,所以经过大量研究。。。我已经找到了要重写的适当类,现在可以根据请求检查控制器是否能够被解析,如果不能,则尝试将适当的程序集加载到内存中(基于此时的控制器名称),并返回关联的控制器

代码如下:

public class CustomHttpControllerSelector : DefaultHttpControllerSelector {
  private readonly HttpConfiguration _configuration;

  public CustomHttpControllerSelector(HttpConfiguration configuration) : base(configuration) {
    _configuration = configuration;
  }

  public override HttpControllerDescriptor SelectController(HttpRequestMessage request) {
    HttpControllerDescriptor controller;
    try {
      controller = base.SelectController(request);
    }
    catch (Exception ex) {
      String controllerName = base.GetControllerName(request);
      Assembly assembly = Assembly.LoadFile(String.Format("{0}pak\\{1}.dll", HostingEnvironment.ApplicationPhysicalPath, controllerName));
      Type controllerType = assembly.GetTypes()
        .Where(i => typeof(IHttpController).IsAssignableFrom(i))
        .FirstOrDefault(i => i.Name.ToLower() == controllerName.ToLower() + "controller");
      controller = new HttpControllerDescriptor(_configuration, controllerName, controllerType);
    }
    return controller;
  }
}
当然,您需要替换WebApiConfig的Register方法文件中的服务,如下所示:

config.Services.Replace(typeof(IHttpControllerSelector), new CustomHttpControllerSelector(config));
这里肯定还有更多的工作要做,但这是一个良好的开端。它允许我在托管网站启动和运行时动态地向其添加控制器,而无需中断

这段代码的主要问题显然是新加载的控制器没有添加到已注册控制器的列表中,因此每次请求(对于那些控制器)都会抛出和处理异常。我正在研究是否可以以某种方式将其添加到注册列表中,这样我们就可以看到结果了。

我在这里也有一个答案: