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

Microsoft.Extensions.DependencyInjection解析服务时如何传入额外构造参数

解决方案

你可以直接从DI容器的服务注册描述中获取ISomething对应的实现类型,无需预先创建冗余的默认实例,该方案对现有代码逻辑完全无侵入,也不需要修改第三方实现类。

具体实现思路

  1. 注册服务时将IServiceCollection本身也注册到容器中,方便运行时查询服务注册信息
  2. 需要构造带参实例时,直接从服务描述中取出实现类型,传入ActivatorUtilities.CreateInstance即可

完整代码示例

using System;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;

namespace App
{
  public interface ISomething
  {
    void DoSomething() => Console.WriteLine(nameof(DoSomething));    
  }  
  
  public class Something: ISomething
  {
    public Something() =>
      Console.WriteLine($"{this.GetType().Name} created");

    public Something(object context) =>
      Console.WriteLine($"{this.GetType().Name} created with {context}");
  }

  static class Program
  {
    private static IServiceProvider BuildServices() 
    {
      var services = new ServiceCollection()
        .AddTransient<ISomething, Something>();
      // 注册服务集合本身,用于后续查询服务注册信息
      services.AddSingleton(services);
      return services.BuildServiceProvider();
    }

    static ISomething CreateSomething(IServiceProvider serviceProvider) =>
      serviceProvider.GetRequiredService<ISomething>();

    static ISomething CreateSomethingWithContext(IServiceProvider serviceProvider, object context) 
    {
      // 获取服务注册集合
      var allServices = serviceProvider.GetRequiredService<IServiceCollection>();
      // 查找ISomething对应的服务注册
      var serviceDesc = allServices.FirstOrDefault(d => d.ServiceType == typeof(ISomething));
      if (serviceDesc == null)
        throw new InvalidOperationException("ISomething服务未注册");
      
      // 直接从注册信息中获取实现类型,无需创建任何实例
      var implementationType = serviceDesc.ImplementationType;
      if (implementationType == null)
        throw new InvalidOperationException("无法获取ISomething的实现类型,当前服务为工厂/实例注册");
      
      // 构造带额外参数的实例
      return (ISomething)ActivatorUtilities.CreateInstance(serviceProvider, implementationType, context);
    }

    static void Main()
    {
      var serviceProvider = BuildServices();
      CreateSomething(serviceProvider);
      CreateSomethingWithContext(serviceProvider, Guid.NewGuid());
    }
  }
}

方案优势

  • 无冗余实例创建,避免不必要的性能损耗和初始化副作用
  • 原有使用GetRequiredService<ISomething>()的代码无需任何修改
  • 不需要调整第三方实现类的代码,符合约束条件

注意事项

如果你的ISomething是通过工厂方法或者实例注册的,ImplementationType属性会为null,这种场景下才需要考虑其他兼容方案,普通类型注册的场景可以直接使用该方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 22:18:04