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

.NET通用方法编写:实现适配任意泛型接口的服务注册逻辑

泛型服务注册通用方法实现

你可以将这段代码改写成基于IServiceCollection的扩展方法,通过传入泛型接口的定义类型来适配不同的泛型接口,具体实现如下:

原代码回顾

Assembly.GetExecutingAssembly()
        .GetTypes()
        .Where(item => item.GetInterfaces()
        .Where(i => i.IsGenericType)
        .Any(i => i.GetGenericTypeDefinition() == typeof(IRepository<>)) && !item.IsAbstract && !item.IsInterface)
        .ToList()
        .ForEach(assignedTypes =>
        {
            var serviceType = assignedTypes.GetInterfaces().First(i => i.GetGenericTypeDefinition() == typeof(IRepository<>));
            services.AddScoped(serviceType, assignedTypes);
        });

通用方法实现

public static class ServiceCollectionExtensions
{
    public static void AddGenericServicesFromCurrentAssembly(this IServiceCollection services, Type genericInterfaceDefinition)
    {
        // 校验参数合法性:必须是泛型接口的定义(如 typeof(IRepository<>))
        if (!genericInterfaceDefinition.IsGenericTypeDefinition || !genericInterfaceDefinition.IsInterface)
        {
            throw new ArgumentException("参数必须是泛型接口的定义类型,例如 typeof(IRepository<>)", nameof(genericInterfaceDefinition));
        }

        Assembly.GetExecutingAssembly()
            .GetTypes()
            // 筛选条件:非抽象类、非接口,且实现了目标泛型接口
            .Where(type => 
                !type.IsAbstract && 
                !type.IsInterface &&
                type.GetInterfaces().Any(i => 
                    i.IsGenericType && 
                    i.GetGenericTypeDefinition() == genericInterfaceDefinition))
            .ToList()
            .ForEach(implementationType =>
            {
                // 获取对应的泛型接口类型
                var serviceInterface = implementationType.GetInterfaces()
                    .First(i => 
                        i.IsGenericType && 
                        i.GetGenericTypeDefinition() == genericInterfaceDefinition);
                // 注册为Scoped服务(可根据需求改为AddSingleton/AddTransient)
                services.AddScoped(serviceInterface, implementationType);
            });
    }
}

使用方式

在依赖注入配置中,直接传入目标泛型接口的定义类型即可:

// 注册所有实现IRepository<>的服务
services.AddGenericServicesFromCurrentAssembly(typeof(IRepository<>));

// 注册所有实现IService<>的服务
services.AddGenericServicesFromCurrentAssembly(typeof(IService<>));

关键说明

  • 参数灵活性:通过genericInterfaceDefinition参数替换硬编码的typeof(IRepository<>),支持任意泛型接口
  • 合法性校验:增加参数校验,避免传入错误的类型(比如具体的泛型实例IRepository<User>或非泛型接口)
  • 扩展性:如果需要支持从其他程序集扫描,可新增一个参数传入目标Assembly,替换Assembly.GetExecutingAssembly()
  • 生命周期可调整:当前默认用AddScoped,可根据需求改为AddSingleton或AddTransient,甚至新增参数指定生命周期

内容的提问来源于stack exchange,提问作者dr.Xis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 21:55:08