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

如何在Microsoft DI中解析IReadOnlyCollection而非IEnumerable

问题描述

项目中大量类存在如下依赖:

public class Foo(IReadOnlyCollection<IBar> instances)

使用LightInject进行依赖注入时,该配置默认可正常工作——所有已注册的IBar实现都会在此处被解析。但切换至Microsoft DI后,此配置不再生效,报错信息如下:

System.InvalidOperationException: Unable to resolve service for type 'System.Collections.Generic.IReadOnlyCollection`1[]' while attempting to activate...

请问是否有无需在ServiceCollection中直接注册每个IBar实现,即可解析IReadOnlyCollection<T>的方案?

更新:曾找到一种基于匿名泛型注册IReadOnlyCollection<>的方案,但该方案依赖键注册实现,要求每个IBar注册时都需指定键,操作较为繁琐。


解决方案

可以通过扩展IServiceCollection,为所有泛型类型IReadOnlyCollection<T>添加自动注册逻辑,利用Microsoft DI原生支持的IEnumerable<T>解析能力来实现需求,无需逐个注册IBar实现或依赖键注册。

实现步骤

  1. 添加扩展方法,注册IReadOnlyCollection<T>与ReadOnlyCollection<T>的映射,让DI容器在解析前者时自动转换已注册的IEnumerable<T>实例:
public static class ServiceCollectionExtensions
{
    public static IServiceCollection AddReadOnlyCollectionSupport(this IServiceCollection services)
    {
        // 注册泛型服务:将IReadOnlyCollection<T>绑定到ReadOnlyCollection<T>
        // 容器会自动解析对应的IEnumerable<T>作为构造参数
        services.Add(typeof(IReadOnlyCollection<>), typeof(ReadOnlyCollection<>), ServiceLifetime.Transient);
        return services;
    }
}
  1. 在DI配置中启用该支持(例如Program.cs):
var builder = WebApplication.CreateBuilder(args);
// 注册你的IBar实现(常规方式,无需额外键)
builder.Services.AddTransient<IBar, BarA>();
builder.Services.AddTransient<IBar, BarB>();
// 启用ReadOnlyCollection自动解析支持
builder.Services.AddReadOnlyCollectionSupport();

原理说明

Microsoft DI原生会将所有注册的T实例收集为IEnumerable<T>,而ReadOnlyCollection<T>的构造函数恰好接受IEnumerable<T>参数。通过上述泛型注册,容器在遇到IReadOnlyCollection<IBar>依赖时,会自动解析IEnumerable<IBar>并实例化ReadOnlyCollection<IBar>注入,完全适配原有构造函数的依赖需求。

生命周期适配

如果你的IBar实现使用了Singleton或Scoped生命周期,只需调整扩展方法中的生命周期参数,保持与IEnumerable<T>的生命周期一致即可:

// 例如适配Singleton生命周期
services.Add(typeof(IReadOnlyCollection<>), typeof(ReadOnlyCollection<>), ServiceLifetime.Singleton);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 18:52:36