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

如何通过foreach为MS DI自动注册Func类型依赖?

批量注册Func到MS DI容器的实现方案

假设你已经通过反射拿到了需要处理的ViewModel类型集合(比如IEnumerable<Type> viewModelTypes),可以通过以下方式批量注册对应的Func<T>:

核心思路

通过反射构造Func<T>泛型类型,再利用表达式树创建工厂委托,最后动态调用DI的注册方法完成批量注册。

实现代码

// 先获取AddSingleton的泛型方法定义(如果是Scoped/Transient,替换成对应的方法名)
var addSingletonMethod = typeof(ServiceCollectionServiceExtensions)
    .GetMethod(nameof(ServiceCollectionServiceExtensions.AddSingleton), 
        new[] { typeof(IServiceCollection), typeof(Func<IServiceProvider, object>) });

foreach (var type in viewModelTypes)
{
    // 构造要注册的Func<T>泛型类型
    var funcType = typeof(Func<>).MakeGenericType(type);
    
    // 创建工厂委托:s => () => s.GetRequiredService<T>()
    var factoryDelegate = CreateFuncFactory(type);
    
    // 调用泛版的AddSingleton完成注册
    var genericRegisterMethod = addSingletonMethod.MakeGenericMethod(funcType);
    genericRegisterMethod.Invoke(null, new object[] { services, factoryDelegate });
}

// 辅助方法:构建对应的工厂委托
private static Func<IServiceProvider, object> CreateFuncFactory(Type targetType)
{
    // 用表达式树构建委托逻辑
    var serviceProviderParam = Expression.Parameter(typeof(IServiceProvider), "s");
    
    // 构建s.GetRequiredService<T>()的调用表达式
    var getServiceCall = Expression.Call(
        typeof(ServiceProviderServiceExtensions),
        nameof(ServiceProviderServiceExtensions.GetRequiredService),
        new[] { targetType },
        serviceProviderParam);
    
    // 构建内部无参lambda:() => GetRequiredService<T>()
    var innerLambda = Expression.Lambda(getServiceCall, Array.Empty<ParameterExpression>());
    
    // 构建外部lambda:s => innerLambda(转换为object兼容委托)
    var outerLambda = Expression.Lambda<Func<IServiceProvider, object>>(
        Expression.Convert(innerLambda, typeof(object)),
        serviceProviderParam);
    
    return outerLambda.Compile();
}

注意事项

  • 确保所有ViewModel已经提前注册到DI容器中(你提到已能自动注册这些类型,满足前提)
  • 如果需要注册Scoped或Transient的Func<T>,只需将AddSingleton替换为AddScoped或AddTransient,对应的方法定义获取逻辑保持一致
  • 表达式树的方式比直接用反射创建委托性能更优,且逻辑更清晰

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 01:41:17