C#Web Api中的动态注册控制器 [英] Dynamic register controller in C# Web Api

查看:89
本文介绍了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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆