You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

寻找类似ActivatorUtilities.CreateInstance的显式参数绑定DI实例化方法

依赖注入中显式绑定构造函数参数的标准方案

我们有如下实现了ISomething接口的Something类,其构造函数需要传入字符串参数someText和IAwesomeifier接口实例:

public class Something : ISomething
{
   public string SomeText { get; }
   public IAwesomeifier Awesomeifier { get; }

   public Something(string someText, IAwesomeifier awesomeifier)
   {
      this.SomeText = someText ?? throw new ArgumentNullException(nameof(someText));
      this.Awesomeifier = awesomeifier ?? throw new ArgumentNullException(nameof(awesomeifier));
   }

   // ... 其他业务方法...
}

目前可以通过ActivatorUtilities结合依赖注入(使用Microsoft.Extensions.Hosting和Microsoft.Extensions.DependencyInjection)实例化该类,代码如下:

private static IHost BuildHost()
{
   var builder = Host.CreateApplicationBuilder();
   var services = builder.Services;

   services.AddSingleton<IAwesomeifier, Awesomeifier>();
   services.AddSingleton<ISomething>(provider =>
      ActivatorUtilities.CreateInstance<Something>(
         provider,
         "Here's the text to be awesomeified"));

   return builder.Build();
}

但这种方式依赖构造函数的参数顺序,一旦参数顺序变动就会出错。有没有标准方案可以显式绑定参数值与目标参数,比如类似指定someText:的写法?


可行的标准方案

方案1:使用.NET 6+新增的匿名类型重载(最接近需求)

从.NET 6开始,ActivatorUtilities提供了支持匿名类型传递命名参数的重载,你可以直接通过匿名对象指定参数名和对应的值,DI容器会自动匹配构造函数的参数,同时自动解析其他依赖的服务:

private static IHost BuildHost()
{
    var builder = Host.CreateApplicationBuilder();
    var services = builder.Services;

    services.AddSingleton<IAwesomeifier, Awesomeifier>();
    services.AddSingleton<ISomething>(provider =>
        ActivatorUtilities.CreateInstance<Something>(
            provider,
            new { someText = "Here's the text to be awesomeified" }));

    return builder.Build();
}

方案2:手动构造实例(最直观)

如果不想依赖ActivatorUtilities,可以直接从服务提供者中获取所需的依赖服务,然后手动调用构造函数,这种方式完全显式,不存在参数顺序问题:

private static IHost BuildHost()
{
    var builder = Host.CreateApplicationBuilder();
    var services = builder.Services;

    services.AddSingleton<IAwesomeifier, Awesomeifier>();
    services.AddSingleton<ISomething>(provider =>
    {
        var awesomeifier = provider.GetRequiredService<IAwesomeifier>();
        return new Something("Here's the text to be awesomeified", awesomeifier);
    });

    return builder.Build();
}

方案3:工厂类封装(适合复杂场景)

如果需要复用参数绑定逻辑,或者构造逻辑较为复杂,可以创建工厂类来分离参数和DI依赖:

public class SomethingFactory
{
    private readonly IAwesomeifier _awesomeifier;

    public SomethingFactory(IAwesomeifier awesomeifier)
    {
        _awesomeifier = awesomeifier;
    }

    public Something Create(string someText)
    {
        return new Something(someText, _awesomeifier);
    }
}

然后在DI注册时使用工厂类:

private static IHost BuildHost()
{
    var builder = Host.CreateApplicationBuilder();
    var services = builder.Services;

    services.AddSingleton<IAwesomeifier, Awesomeifier>();
    services.AddSingleton<SomethingFactory>();
    services.AddSingleton<ISomething>(provider =>
    {
        var factory = provider.GetRequiredService<SomethingFactory>();
        return factory.Create("Here's the text to be awesomeified");
    });

    return builder.Build();
}

内容的提问来源于stack exchange,提问作者Bob Vesterman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 20:38:23