Web API 2是否可以以编程方式加载路径/控制器?

Xor*_*ist 8 asp.net-web-api asp.net-web-api-routing programmatically-created

我目前正在开发一个使用WCF实现REST API的企业Web应用程序.它采用的VirtualPathProvider赶上请求*.SVC文件(实际上并不存在),然后建立他们的飞行动态加载相关的WCF服务.这允许系统具有可以在运行时添加到应用程序的"模块",而不会影响Web服务器或使用它的任何人.

我想知道的是,如果在概念上可以使用Web API 2.我一直在做一些研究,但看起来路由只能在启动时配置...我希望的是一种手段处理为不存在的路线,并且基本上使用控制器名称从请求到查找和装载相关联的组件(如果存在),而编程添加新路由.

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

Xor*_*ist 9

好的,经过多次研究后......我已经找到了要覆盖的正确类,现在可以按要求检查控制器是否能够被解析,如果没有,则尝试将正确的程序集加载到内存中(根据此时的控制器名称),并返回相关的控制器.

这是代码:

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;
  }
}
Run Code Online (Sandbox Code Playgroud)

当然,你需要在WebApiConfig的Register方法文件中替换服务:

config.Services.Replace(typeof(IHttpControllerSelector), new CustomHttpControllerSelector(config));
Run Code Online (Sandbox Code Playgroud)

这里肯定还有很多工作要做,但这是一个好的开始.它允许我在托管网站启动和运行时动态添加控制器,而不需要中断.

这段代码的主要问题显然是新加载的控制器没有添加到已注册的控制器列表中,因此总是抛出异常并处理每个请求(对于那些控制器).我正在研究是否可以通过某种方式将其添加到注册列表中,因此我们将看到这导致了什么.