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

Autofac如何注册类层级结构并通过枚举解析对应服务实例

解决Autofac多级继承接口按枚举匹配实例的通用方案

前置修正

你提供的抽象类代码存在语法问题,抽象方法声明缺少返回值,修正为:

public abstract class MyServiceA : IMyService
{
    public abstract void DoMyService();
}
public abstract class MyServiceB : IMyService
{
    public abstract void DoMyService();
}

1. 定义枚举关联特性

用于给具体实现类绑定对应的枚举匹配规则:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class ServiceIdentifierAttribute : Attribute
{
    public FirstEnum FirstType { get; }
    public SecondEnum SecondType { get; }

    public ServiceIdentifierAttribute(FirstEnum firstType, SecondEnum secondType)
    {
        FirstType = firstType;
        SecondType = secondType;
    }
}

2. 标记所有具体实现类

给四个现有实现类添加对应特性,后续新增实现类也只需按规则标记即可:

[ServiceIdentifier(FirstEnum.SvcA, SecondEnum.Svc1)]
public class MyServiceA1 : MyServiceA
{
    // 原有实现不变
}

[ServiceIdentifier(FirstEnum.SvcA, SecondEnum.Svc2)]
public class MyServiceA2 : MyServiceA
{
    // 原有实现不变
}

[ServiceIdentifier(FirstEnum.SvcB, SecondEnum.Svc1)]
public class MyServiceB1 : MyServiceB
{
    // 原有实现不变
}

[ServiceIdentifier(FirstEnum.SvcB, SecondEnum.Svc2)]
public class MyServiceB2 : MyServiceB
{
    // 原有实现不变
}

3. Autofac通用注册逻辑

通过反射扫描实现类自动注册,无需后续新增实现时修改注册代码:

var builder = new ContainerBuilder();

// 扫描指定程序集内所有非抽象的IMyService实现类
var serviceImplTypes = typeof(IMyService).Assembly.GetTypes()
    .Where(t => 
        typeof(IMyService).IsAssignableFrom(t) 
        && t.IsClass 
        && !t.IsAbstract);

foreach (var implType in serviceImplTypes)
{
    // 读取类上的枚举绑定特性
    var identifier = implType.GetCustomAttribute<ServiceIdentifierAttribute>();
    if (identifier == null) continue;
    
    // 以两个枚举组合为Key,注册键控服务
    var serviceKey = Tuple.Create(identifier.FirstType, identifier.SecondType);
    builder.RegisterType(implType).Keyed<IMyService>(serviceKey);
}

// 注册实例解析工厂,注入后可直接使用
builder.Register<Func<FirstEnum, SecondEnum, IMyService>>(ctx =>
{
    var context = ctx.Resolve<IComponentContext>();
    return (firstType, secondType) =>
    {
        var key = Tuple.Create(firstType, secondType);
        return context.ResolveKeyed<IMyService>(key);
    };
});

// 构建容器(你的原有逻辑)
var container = builder.Build();

4. 使用示例

在需要使用服务的类中注入解析工厂,传入枚举即可获取对应实例:

public class BusinessService
{
    private readonly Func<FirstEnum, SecondEnum, IMyService> _serviceFactory;

    // 构造函数注入工厂
    public BusinessService(Func<FirstEnum, SecondEnum, IMyService> serviceFactory)
    {
        _serviceFactory = serviceFactory;
    }

    public void ExecuteBusiness()
    {
        // 传入枚举即可拿到匹配的实例,示例中拿到的是MyServiceB2实例
        var service = _serviceFactory(FirstEnum.SvcB, SecondEnum.Svc2);
        service.DoMyService();
    }
}

扩展说明

后续新增IMyService的具体实现时,只需完成两步即可自动生效:

  1. 继承对应抽象类,实现业务逻辑
  2. 给类添加ServiceIdentifierAttribute,指定匹配的枚举值
    无需修改任何注册或工厂逻辑。

内容的提问来源于stack exchange,提问作者J.Doe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 09:12:03