为啥 Asp.net web api 控制器不从 IController 派生

Posted

技术标签:

【中文标题】为啥 Asp.net web api 控制器不从 IController 派生【英文标题】:Why doesn't Asp.net web api controllers derive from IController为什么 Asp.net web api 控制器不从 IController 派生 【发布时间】:2012-03-18 18:29:04 【问题描述】:

在 ASP.net MVC4 中,有一个 Web API 的“新”概念,用于在数据模型上公开 CRUD 功能。这些控制器的基类是DataController,它派生自ApiController

不幸的是,这个ApiController 不是从IController 派生的,这是有问题的,因为这些请求无法通过您的常规自定义控制器工厂处理,因为它们应该返回IController 的实例。

有谁知道这背后的原因,因为我不明白为什么您的 MVC 项目中会有一个不是从 IController 派生的控制器,因为这会破坏您的自定义控制器工厂,因为它无法实例化每一个项目中的控制器。

简而言之,由于这种继承,您无法使用 DI 容器来注入依赖项。

【问题讨论】:

【参考方案1】:

我也向 Microsoft 发送了同样的问题,并得到了 Eilon Lipton 的以下回复(感谢):

简而言之,虽然 ASP.NET MVC 和 ASP.NET Web API 共享许多相同的设计概念(依赖注入、大量用于插入自定义实现的接口以及易于测试),但它们构建在不同的底层之上HTTP 堆栈。 MVC 建立在已在 ASP.NET 中使用了 10 多年的 System.Web 堆栈之上。 Web API 建立在新的 System.Net.Http 堆栈之上,它为托管(IIS + 自定义主机 + 单元测试主机)提供了更大的灵活性以及更好的可测试性和可扩展性。如果您比较 IController 和 IHttpController,您会发现其中一个在堆栈上下使用 System.Web,而另一个根本不使用它。

无论如何,构建在 ASP.NET 堆栈上的所有技术——MVC、Web 窗体、Web API、网页(和 Razor)——将继续在应用程序中并行工作,允许您选择正确的部分来构建应用程序的每个部分。虽然每个部分中组件的单独实现不可互换,但它们都可以连接到相同的服务,例如依赖注入系统、日志工具、数据提供者等。

一旦我们发布了关于这个主题的帖子,我认为应该进一步澄清事情。

【讨论】:

【参考方案2】:

要使用 ASP.Net WebAPI 进行 DI,您需要为您的 DI 容器创建依赖关系解析器。

以下适用于 Ninject

public class NinjectDependencyResolver : System.Web.Http.Services.IDependencyResolver

    private static IKernel m_Kernel;

    public NinjectDependencyResolver()
    
        m_Kernel = new StandardKernel();
    

    public NinjectDependencyResolver(IKernel myKernel)
    
        m_Kernel = myKernel;
    

    public object GetService(Type serviceType)
    
        return m_Kernel.TryGet(serviceType);
    

    public IEnumerable<object> GetServices(Type serviceType)
    
        return m_Kernel.GetAll(serviceType);
    

然后使用以下命令将其绑定到 Global.ascx 文件中:

GlobalConfiguration.Configuration.ServiceResolver.SetResolver(new NinjectDependencyResolver(yourKernel));

这与 MVC3 依赖注入相似(但不完全相同)

【讨论】:

我以前使用过我自己的控制器工厂,即使对于 webapi 控制器,仍然会调用这个类。我无法让应用程序调用 DependencyResolver。所有请求都通过我自己的 ControllerFactory(删除这个自定义工厂并不会改变)。

以上是关于为啥 Asp.net web api 控制器不从 IController 派生的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的异步 ASP.NET Web API 控制器阻塞了主线程?

为啥从 ASP.NET Core Web API 的 ControllerBase 与 Controller 派生?

为啥当包含控制器动作的数据时日期时间值会发生变化?使用 AngularJs 和 Asp.Net Web API 2

为啥 ASP.NET web api 3 项目在 ASP.NET web api 2 执行时没有请求就无法启动?

Web API系列教程2.1 — ASP.NET Web API中的路由机制

所有 ASP.NET Web API 控制器都返回 404