Reputation: 1335
I would like to disable the automatic discovery of controllers while self-hosting WebApi, and manually nominate controllers and associate them with routes at run time.
Filip W has a nice write-up on customising controller discovery which leads me to believe that I could simply implement IHttpControllerTypeResolver
or IAssembliesResolver
to manipulate the automatic discovery into doing nothing, but this only solves half the problem, and it feels like a poor solution for the half of the problem it addresses - I want to effectively disable discovery; but this feels more like butchering discovery but keeping it around...?
Once discovery is disabled, I would like to compensate by nominating a controller (or controller factory?) that will be determined prior to the server initialisation. I could possibly handle the routing aspect with IHttpControllerSelector
however I can't see how I am supposed to otherwise nominate a controller such that WebApi is aware of it for this to work.
In summary I want to:
What is the most appropriate method to achieve this (if any)?
I am not tied to specific versions of anything; currently using .Net framework 4.7.2 and Microsoft.AspNet.WebApi.OwinSelfHost
5.2.6.
Upvotes: 4
Views: 1655
Reputation: 249
I think the HttpControllerSelector ist the right way to do this. Here is a small example:
HttpControllerSelector:
public class HttpControllerSelector : IHttpControllerSelector
{
private readonly HttpConfiguration _httpConfiguration;
public HttpControllerSelector(HttpConfiguration httpConfiguration)
{
this._httpConfiguration = httpConfiguration;
}
public HttpControllerDescriptor SelectController(HttpRequestMessage request)
{
return new HttpControllerDescriptor(this._httpConfiguration,
nameof(ValuesController),
typeof(ValuesController));
}
public IDictionary<string, HttpControllerDescriptor> GetControllerMapping()
{
var mapping = new Dictionary<string, HttpControllerDescriptor>
{
{
nameof(ValuesController),
new HttpControllerDescriptor(this._httpConfiguration,
nameof(ValuesController),
typeof(ValuesController))
}
};
return mapping;
}
}
WebApiConfig:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
config.Services.Replace(typeof(IHttpControllerSelector), new HttpControllerSelector(config));
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
So, in the HttpControllerSelector, you can do everything you want. As a simple example, there is a controller which one is always selected. At this point you can use a factory or something that suits you.
To disable the normal discovery, you have to override the normal Selector shown in the WebApiConfig.
Hope this gave your an idea how to do it, happy coding!
Upvotes: 2