源码解析:ASP.NET Core Controller与IOC的羁绊

Posted DotNET技术圈

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了源码解析:ASP.NET Core Controller与IOC的羁绊相关的知识,希望对你有一定的参考价值。

前言

    看到标题可能大家会有所疑问Controller和IOC能有啥羁绊,但是我还是拒绝当一个标题党的。相信有很大一部分人已经知道了这么一个结论,默认情况下ASP.NET Core的Controller并不会托管到IOC容器中,注意关键字我说的是"默认",首先咱们不先说为什么,如果还有不知道这个结论的同学们可以自己验证一下,验证方式也很简单,大概可以通过以下几种方式。

验证Controller不在IOC中

首先,我们可以尝试在ServiceProvider中获取某个Controller实例,比如

public void Configure(IApplicationBuilder app, IWebHostEnvironment env){ var productController = app.ApplicationServices.GetService<ProductController>();}

这是最直接的方式,可以在IOC容器中获取注册过的类型实例,很显然结果会为null。另一种方式,也是利用它的另一个特征,那就是通过构造注入的方式,如下所示我们在OrderController中注入ProductController,显然这种方式是不合理的,但是为了求证一个结果,我们这里仅做演示,强烈不建议实际开发中这么写,这是不规范也是不合理的写法

public class OrderController : Controller{ private readonly ProductController _productController; public OrderController(ProductController productController) { _productController = productController; }
public IActionResult Index() { return View(); }}

结果显然是会报一个错InvalidOperationException: Unable to resolve service for type 'ProductController' while attempting to activate 'OrderController'。原因就是因为ProductController并不在IOC容器中,所以通过注入的方式会报错。还有一种方式,可能不太常用,这个是利用注入的一个特征,可能有些同学已经了解过了,那就是通过自带的DI,即使一个类中包含多个构造函数,它也会选择最优的一个,也就是说自带的DI允许类包含多个构造函数。利用这个特征,我们可以在Controller中验证一下

public class OrderController : Controller{ private readonly IOrderService _orderService; private readonly IPersonService _personService;
public OrderController(IOrderService orderService) { _orderService = orderService; }
public OrderController(IOrderService orderService, IPersonService personService) { _orderService = orderService; _personService = personService; }
public IActionResult Index() { return View(); }}

我们在Controller中编写了两个构造函数,理论上来说这是符合DI特征的,运行起来测试一下,依然会报错InvalidOperationException: Multiple constructors accepting all given argument types have been found in type 'OrderController'. There should only be one applicable constructor。以上种种都是为了证实一个结论,默认情况下Controller并不会托管到IOC当中。

DefaultControllerFactory源码探究

    上面虽然我们看到了一些现象,能说明Controller默认情况下并不在IOC中托管,但是还没有足够的说服力,接下来我们就来查看源码,这是最有说服力的。我们找到Controller工厂注册的地方,在MvcCoreServiceCollectionExtensions扩展类中[点击查看源码

以上是关于源码解析:ASP.NET Core Controller与IOC的羁绊的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core 2.2 CORS 没有“Access-Control-Allow-Origin”标头 [关闭]

Angular 6 与 Asp.net Core 2.1 不存在“Access-Control-Allow-Origin”标头

Asp.Net Core缓存管理

Asp.Net Core缓存管理

Asp.Net Core缓存管理

ASP .NET Core 中的 CORS 问题 - 响应中的“Access-Control-Allow-Origin”标头的值不能是通配符 '*