验证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扩展类中[点击查看源码
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。