具有多个构造函数的ASP.NET 5 MVC 6依赖注入

Muh*_*eed 13 asp.net dependency-injection asp.net-core-mvc asp.net-core

我的ASP.NET 5应用程序中有一个带有多个构造函数的标记助手.当ASP.NET 5尝试解析类型时,这会在运行时导致以下错误:

InvalidOperationException:在"MyNameSpace.MyTagHelper"类型中找到了接受所有给定参数类型的多个构造函数.应该只有一个适用的构造函数.

其中一个构造函数是无参数的,另一个构造函数的参数不是注册类型.我希望它使用无参数构造函数.

有没有办法让ASP.NET 5依赖注入框架选择一个特定的构造函数?通常这是通过使用属性完成的,但我找不到任何东西.

我的用例是我正在尝试创建一个既是TagHelper的单个类,也是一个HTML帮助器,如果这个问题得到解决,这个完全有可能.

Kév*_*let 19

Illya是对的:内置解析器不支持暴露多个构造函数的类型......但是没有什么能阻止您注册代理来支持这种情况:

services.AddScoped<IService>(provider => {
    var dependency = provider.GetRequiredService<IDependency>();

    // You can select the constructor you want here.
    return new Service(dependency, "my string parameter");
});
Run Code Online (Sandbox Code Playgroud)

注意:在更高版本中添加了对多个构造函数的支持,如其他答案中所示.现在,DI堆栈将很乐意选择具有可解析的最多参数的构造函数.例如,如果你有2个构造函数 - 一个有3个参数指向服务而另一个有4个 - 它将更喜欢具有4个参数的构造函数.


Mah*_*ahi 14

ASP.NET Core 2.1及更高版本

您可以ActivatorUtilitiesConstructorAttribute在要在DI中使用的构造函数上使用:

[ActivatorUtilitiesConstructor]
public MyClass(ICustomDependency d)
{
}
Run Code Online (Sandbox Code Playgroud)

  • 这太棒了,因为我可以有 2 个构造函数。一种是供 DI 注入 IConfiguration,另一种是在我的集成测试中使用,我可以在其中指定连接字符串。 (5认同)
  • 像魅力一样工作,应该检查为已接受的答案。 (4认同)
  • 这会将构造函数标记为首选构造函数,还是将构造函数标记为唯一可用的构造函数?当有多个构造函数可用时,有什么方法可以设置优先顺序吗? (3认同)
  • 仅通过“ActivatorUtilities.CreateInstance/CreateFactory”方法直接创建的类才支持此属性。使用标准注册时会忽略它,例如“AddTransient&lt;ISomething, Something&gt;”。请考虑更新您的回复以明确这一点,并表明需要手动调用激活器来拾取它,例如“AddTransient&lt;ISomething&gt;(p =&gt; ActivatorUtilities.CreateInstance&lt;Something&gt;(p));” (3认同)