已基于DI框架构建的服务中引入局部依赖注入模式的需求问询
局部化依赖注入解决步骤工厂的样板代码问题
针对你遇到的步骤工厂冗余、依赖传递混乱的问题,可以通过基于根服务容器创建局部服务集合的方式,实现步骤的自动依赖注入,同时隔离不同流程的接口实例。
实现步骤
1. 构建局部步骤上下文
创建一个上下文类,负责初始化局部服务容器,绑定当前流程的步骤和它们实现的接口:
public class StepCreationContext { public IServiceProvider LocalServiceProvider { get; } public StepCreationContext(IServiceProvider rootProvider, Dictionary<string, object> request) { var localServices = new ServiceCollection(); // 注册当前请求参数,让所有步骤可以直接注入 localServices.AddSingleton(request); // 绑定步骤及其实现的特定接口(仅在当前流程生效) localServices.AddSingleton<InitializeStep>(); // 将InitializeStep实例绑定为当前流程的IAuthenticationProvider localServices.AddSingleton<IAuthenticationProvider>(sp => sp.GetRequiredService<InitializeStep>()); localServices.AddSingleton<ProcessingStep>(); // 按需求添加其他步骤... // 基于根容器构建局部容器,复用全局服务(如INecessaryServiceFoo/Bar) LocalServiceProvider = localServices.BuildServiceProvider(new ServiceProviderOptions { ValidateScopes = true, ValidateOnBuild = true }, rootProvider); } }
2. 简化StepListCreator
改造后的工厂类仅负责定义步骤顺序,无需手动处理参数和依赖传递:
public class StepListCreator { private readonly IServiceProvider _rootServiceProvider; public StepListCreator(IServiceProvider rootServiceProvider) { _rootServiceProvider = rootServiceProvider; } public List<IStep> Create(Dictionary<string, object> request) { var context = new StepCreationContext(_rootServiceProvider, request); var localProvider = context.LocalServiceProvider; // 仅按执行顺序获取步骤,依赖由局部容器自动注入 return new List<IStep> { localProvider.GetRequiredService<InitializeStep>(), localProvider.GetRequiredService<ProcessingStep>(), // 添加其他步骤... }; } }
3. 调整步骤类的构造函数
让步骤通过构造函数注入所需的所有依赖,包括请求参数、全局服务和跨步骤接口:
public class InitializeStep : IStep, IAuthenticationProvider { private readonly object _initParams; private readonly INecessaryServiceBar _serviceBar; public InitializeStep(Dictionary<string, object> request, INecessaryServiceBar serviceBar) { _initParams = request["init"]; _serviceBar = serviceBar; } // 实现IStep和IAuthenticationProvider接口... } public class ProcessingStep : IStep { private readonly object _procParams; private readonly IAuthenticationProvider _authProvider; private readonly INecessaryServiceFoo _serviceFoo; public ProcessingStep(Dictionary<string, object> request, IAuthenticationProvider authProvider, INecessaryServiceFoo serviceFoo) { _procParams = request["proc"]; _authProvider = authProvider; _serviceFoo = serviceFoo; } // 实现IStep接口... }
核心优势
- 彻底消除样板代码:工厂类不再需要手动实例化步骤、传递参数,只需维护执行顺序
- 局部实例隔离:每个流程的IAuthenticationProvider实例是独立的,不会和其他流程的实例冲突
- 自动依赖解析:所有步骤的依赖(包括全局服务、请求参数、跨步骤接口)由局部容器自动处理
- 复用全局服务:局部容器可以直接从根容器获取INecessaryServiceFoo等全局注册的服务,无需重复配置
内容的提问来源于stack exchange,提问作者user2015635
相关产品推荐
相关产品推荐

