求助:基于Autofac实现按枚举类型创建Person/Doctor实例的工厂方法
用Autofac替代简单工厂实现参与者生成逻辑
没问题,我来帮你把现有的简单工厂逻辑迁移到Autofac框架上,这样能更好地利用依赖注入的优势,减少硬编码的实例创建。咱们一步步来实现:
1. 完成Autofac容器的注册配置
首先需要把你的Person和Doctor类型注册为IParticipant的命名服务,让Autofac能根据名称区分不同的实现:
var builder = new ContainerBuilder(); // 注册Person为命名服务,名称对应枚举值 builder.RegisterType<Person>() .Named<IParticipant>(PersonType.Person.ToString()); // 注册Doctor为命名服务,名称对应枚举值 builder.RegisterType<Doctor>() .Named<IParticipant>(PersonType.Doctor.ToString()); // 注册RandomParticipantGenerator,注入容器上下文用于解析服务 builder.RegisterType<RandomParticipantGenerator>() .As<IParticipantGenerator>() .InstancePerDependency(); // 按需创建实例,可根据需求调整生命周期 var container = builder.Build();
2. 改造RandomParticipantGenerator类
原来的工厂方法是直接new实例,现在我们让它依赖Autofac的IComponentContext,这样就能从容器中解析对应的IParticipant实例,同时传递State参数:
class RandomParticipantGenerator : IParticipantGenerator { private readonly IComponentContext _componentContext; // 通过构造函数注入容器上下文 public RandomParticipantGenerator(IComponentContext componentContext) { _componentContext = componentContext ?? throw new ArgumentNullException(nameof(componentContext)); } public enum PersonType { Person, Doctor } public IParticipant GetParticipant(PersonType type, State state) { // 将枚举转换为服务名称,匹配注册时的命名 var serviceName = type.ToString(); // 解析对应IParticipant实例,并传入State构造参数 return _componentContext.ResolveNamed<IParticipant>( serviceName, new TypedParameter(typeof(State), state)); } public List<IParticipant> GetParticipants(PersonType type, State state, int numOfPeople) { var participants = new List<IParticipant>(); for (int i = 0; i < numOfPeople; i++) { participants.Add(GetParticipant(type, state)); } return participants; } }
3. 关键细节说明
- 命名服务的作用:因为
Person和Doctor都实现了IParticipant,用命名服务可以让Autofac明确知道要解析哪一个实现,完美匹配你的PersonType枚举逻辑。 - 构造参数传递:如果你的
Person或Doctor类的构造函数需要State参数,ResolveNamed方法里的TypedParameter会自动把state值传递给构造函数,无需手动new实例。 - 生命周期管理:注册
RandomParticipantGenerator时的InstancePerDependency是默认生命周期,每次解析都会创建新实例,你可以根据实际需求改成SingleInstance(单例)或者其他生命周期模式。
4. 调用示例
最后你可以这样从容器中获取IParticipantGenerator并使用:
using (var scope = container.BeginLifetimeScope()) { var generator = scope.Resolve<IParticipantGenerator>(); var doctor = generator.GetParticipant(RandomParticipantGenerator.PersonType.Doctor, new State()); var personList = generator.GetParticipants(RandomParticipantGenerator.PersonType.Person, new State(), 5); }
这样就完全用Autofac的依赖注入替代了原来的简单工厂逻辑,代码更解耦,也更符合DI的设计原则。
内容的提问来源于stack exchange,提问作者Arik Shapiro
相关产品推荐
相关产品推荐

