好的,所以经过大量研究......我已经找到了要覆盖的正确类,现在可以根据请求检查控制器是否能够被解析,如果不能,尝试将正确的程序集加载到内存中(基于当前的控制器名称),并返回关联的控制器。
这是代码:
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));
这里肯定还有更多工作要做,但这是一个好的开始。它允许我在托管网站启动和运行时动态地将控制器添加到它,而无需中断。
这段代码的主要问题显然是新加载的控制器没有添加到已注册控制器的列表中,因此总是在每个请求(对于那些控制器)上抛出和处理异常。我正在研究是否可以以某种方式将其添加到注册列表中,因此我们将看看这会导致什么。