在ConfigureServices中注册服务时,将调用哪个构造函数?

8
如果一个类有两个构造函数,当我在ConfigureServices中注册该服务时,服务容器会如何选择使用哪个构造函数?
假设我有一个名为MyClass的类及其对应的接口IMyClass。在ConfigureServices()方法中,我调用了以下代码:
services.AddScoped<IMyClass, MyClass>();

如果我有以下构造函数,它如何选择使用哪个构造函数?
MyClass(ILogger logger)

MyClass(ILogger logger, IConfguration configuration)

不能确定,但我相信它会使用默认的构造函数(既不是你的任何一个构造函数)。 - Jawad
4
它将使用构造函数满足最多的依赖项,即在您的情况下使用底部的构造函数。 - JohanP
行为是使用已知参数的第一个匹配的构造函数。 - majita
2个回答

11
构造函数匹配是通过一个叫做CallSiteFactory:CreateConstructorCallSite的方法来执行的。根据其源代码,算法如下:
- 找到目标类型的所有公共构造函数 - 如果没有,则抛出异常 - 如果只有一个,则使用它 - 按参数数量对所有构造函数进行排序(参数最多的构造函数排在前面) - 选择可以被 DI 注入最多参数的构造函数 - 如果有多个这样的构造函数,则抛出异常 - 如果没有可用的构造函数,则抛出异常
为了澄清何时可能存在歧义,请考虑以下构造函数:
MyClass(ILogger logger)
MyClass(IConfguration configuration)

DI引擎无法决定使用哪个,因为两个都有可以注入的有效参数。
然而,在下面的情况中,没有歧义,因为int类型未在DI引擎中注册,因此不能通过DI进行注入,因此将选择第一个构造函数。
MyClass(ILogger logger)
MyClass(int i)

所以回答你的问题:在你的情况下,将使用第二个构造函数。

0

我用以下案例进行了测试:

  1. 一个带有接口(已注册)和一个带有接口和原始参数(未注册)的1

    public Application(ITestClass testClass)

    public Application(ITestClass testClass, string message)

它选择了第一个。

  1. 一个带有接口(已注册)和两个接口(已注册)的1

    public Application(ITestClass testClass)

    public Application(ITestClass testClass, ITestClass2 testClass2)

它选择了第二个。

  1. 一个带有接口(已注册),一个带有2个接口(已注册)和一个原始参数(未注册)的1

    public Application(ITestClass testClass)

    public Application(ITestClass testClass, ITestClass2 testClass2, string message)

它再次选择了第一个。

当我注册字符串类型时,它开始选择第二个。

简而言之,它将尝试查找具有唯一已知依赖项的最全面的内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接