C#Web Api中的动态注册控制器 [英] Dynamic register controller in C# Web Api
问题描述
tl; dr:我(通过反射)正在创建扩展 ApiController
的 Type
.如何动态注册(可以在启动时注册;无需在运行时注册).
tl;dr: I'm creating Type
(by reflection) that is extending ApiController
. How can I dynamically register it (it can be registered at startup; no need to do this at runtime).
长话短说
所以在我的应用程序中,我有多个接口,即:
So in my application I have multiple interfaces, i.e.:
interface IMyInterface
{
MyResponse Hello(MyRequest request);
}
我要实现的功能是为每个接口创建控制器,其外观应如下所示:
The thing that I want to achive is for each interface create controller that should look like this:
public class IMyInterfaceController : ApiController
{
public IMyInterface MyInterface { get; set; }
public MyResponse Hello([FromBody] MyRequest request)
{
return MyInterface.Hello(request);
}
}
已经使用大量C#反射完成了此控制器的生成.我现在要做的是在/api/{controller}/{action}
下注册此控制器.
Generating this controller is already done using heavy C# reflection. The thing is that I want to do right now is to register this controller under /api/{controller}/{action}
.
现在在 Global.asax
中,我得到了:
public class MvcApplication : System.Web.HttpApplication
{
private readonly InterfaceReader _reader = new InterfaceReader(); // this class is doing all staff with reflection to create controller class
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
var controller = _reader.CreateController(new MyImplementation()); // MuImplementation implements IMyInterface
}
}
推荐答案
使用 IHttpControllerFactory
的解决方案我想您需要的是控制器工厂:
Solution with IHttpControllerFactory
I guess that what you need is a controller factory:
public class MyHttpControllerFactory : IHttpControllerFactory
{
private readonly InterfaceReader _reader;
private readonly HttpConfiguration _configuration;
public MyHttpControllerFactory(InterfaceReader reader, HttpConfiguration configuration)
{
_reader = reader;
_configuration = configuration;
}
public IHttpController CreateController(HttpControllerContext controllerContext, string controllerName)
{
if (controllerName == null)
{
throw new HttpException(404, string.Format("The controller for path '{0}' could not be found.", controllerContext.Request.RequestUri.AbsolutePath));
}
// Change the line below to whatever suits your needs.
var controller = _reader.CreateController(new MyImplementation());
controllerContext.Controller = controller;
controllerContext.ControllerDescriptor = new HttpControllerDescriptor(configuration, controllerName, controller.GetType());
return controllerContext.Controller;
}
public void ReleaseController(IHttpController controller)
{
// You may want to be able to release the controller as well.
}
}
然后在 Global.asax
中,您需要注册自定义控制器工厂:
Then in the Global.asax
you need to register the custom controller factory:
public class MvcApplication : System.Web.HttpApplication
{
private readonly InterfaceReader _reader = new InterfaceReader(); // this class is doing all staff with reflection to create controller class
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
GlobalConfiguration.Configuration.ServiceResolver.SetService(typeof(IHttpControllerFactory), new MyHttpControllerFactory(_reader, GlobalConfiguration.Configuration));
}
}
使用 IHttpControllerActivator
的解决方案如果使用Web Api 2,则解决方案是使用 IDependencyResolver
或 IHttpControllerActivator
代替工厂.我想 IHttpControllerActivator
在您的情况下是更好的选择.
Solution with IHttpControllerActivator
If you use Web Api 2 then the solution is to use either IDependencyResolver
or IHttpControllerActivator
instead of the factory. I guess that the IHttpControllerActivator
is better option in your case.
public class MyServiceActivator : IHttpControllerActivator
{
private readonly InterfaceReader _reader;
private readonly HttpConfiguration _configuration;
public MyServiceActivator(InterfaceReader reader, HttpConfiguration configuration)
{
_reader = reader;
_configuration = configuration;
}
public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
{
// Change the line below to whatever suits your needs.
var controller = _reader.CreateController(new MyImplementation());
return controller;
}
}
然后在 Global.asax
中注册自定义激活器:
Then in the Global.asax
you need to register the custom activator:
public class MvcApplication : System.Web.HttpApplication
{
// this class is doing all staff with reflection to create controller class
private readonly InterfaceReader _reader = new InterfaceReader();
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
HttpConfiguration config = GlobalConfiguration.Configuration;
config.Services.Replace(typeof(IHttpControllerActivator), new MyServiceActivator(_reader, config));
}
}
我希望这会有所帮助.
这篇关于C#Web Api中的动态注册控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!