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的具体实现时,只需完成两步即可自动生效:
- 继承对应抽象类,实现业务逻辑
- 给类添加
ServiceIdentifierAttribute,指定匹配的枚举值
无需修改任何注册或工厂逻辑。
内容的提问来源于stack exchange,提问作者J.Doe
相关产品推荐
相关产品推荐

