You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

ASP.NET Core DI:如何按基类型获取实例及实现派生类单次注册?

一次性注册所有MyBaseClass派生类到DI容器的方法

当然有更高效的方式!你现在手动逐个注册的方式确实繁琐,尤其是派生类数量多的时候。下面我给你分享一种基于反射的批量注册方案,只需要一次调用就能搞定所有派生类的注册:

实现思路

通过反射扫描指定程序集,自动找到所有继承自MyBaseClass的非抽象派生类,然后批量完成两个核心注册操作:

  1. 注册派生类本身到DI容器
  2. 注册MyBaseClass到该派生类的映射,这样调用GetServices<MyBaseClass>()就能获取到所有派生类实例

扩展方法实现

我们可以写一个IServiceCollection的扩展方法,让注册逻辑复用性更强:

using Microsoft.Extensions.DependencyInjection;
using System.Reflection;

public static class ServiceCollectionExtensions
{
    public static IServiceCollection AddAllDerivedTypes<TBase>(this IServiceCollection services, ServiceLifetime lifetime = ServiceLifetime.Singleton)
    {
        // 扫描当前程序集中所有符合条件的派生类
        var derivedTypes = Assembly.GetExecutingAssembly()
            .GetTypes()
            .Where(t => t.IsClass && !t.IsAbstract && typeof(TBase).IsAssignableFrom(t));

        foreach (var type in derivedTypes)
        {
            // 注册派生类自身
            services.Add(new ServiceDescriptor(type, type, lifetime));
            // 注册基类到派生类的映射
            services.Add(new ServiceDescriptor(typeof(TBase), sp => sp.GetRequiredService(type), lifetime));
        }

        return services;
    }
}

使用方式

在你的DI配置代码(比如Program.csStartup.cs)中,只需要一行代码就能完成所有派生类的注册:

// 默认注册为Singleton生命周期
services.AddAllDerivedTypes<MyBaseClass>();

// 也可以指定其他生命周期,比如Scoped
// services.AddAllDerivedTypes<MyBaseClass>(ServiceLifetime.Scoped);

注意事项

  • 跨程序集扫描:如果你的派生类分布在其他程序集中,需要把Assembly.GetExecutingAssembly()替换为对应的程序集,比如typeof(SomeDerivedClass).Assembly(通过某个派生类获取其所在程序集),或者Assembly.Load("YourTargetAssemblyName")
  • 构造函数要求:确保所有派生类的构造函数参数都能被DI容器解析(比如参数类型已经注册到容器中)。
  • 泛型派生类:如果有泛型形式的派生类,上述方法需要额外调整逻辑来处理泛型类型,不过对于非泛型的普通派生类场景,这个方案完全够用。

这样你就不用再手动逐个注册每个派生类了,一次调用就能完成所有需要的注册操作,后续新增派生类也不需要修改注册代码,非常方便!

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

火山引擎 最新活动