.NET中状态模式如何结合依赖注入?
状态模式与.NET依赖注入结合的问题
我正在学习.NET中的设计模式,尝试实现状态模式时遇到了无法解决的问题:
我有多个实现了IOperationState接口的状态类,其中最后一个FinalState需要通过.NET API的Startup类注入的IPersistenceService连接数据库,完成数据持久化并结束流程。但FinalState需要依赖注入,我无法直接实例化它来推进流程,不确定是模式使用错误,还是模式与依赖注入的结合方式有问题。下面是模拟的代码结构:
状态接口与OperatingClass
public interface IOperationState { public int ExecuteOperation(OperatingClass operatingClass); } public class OperatingClass { public IOperationState OperationState { get; set; } public int id { get; set; } public double value { get; set; } public OperatingClass(int id) //constructor { this.id = id; value = 0; OperationState = new StartingState(); } public int Execute() { return OperationState.ExecuteOperation(this); } }
主服务MainService
public class MainService { public int ExecuteFullOperation(int id) { //Receives an id and execute the state transition till the end; var operatingClass = new OperatingClass(id); return operatingClass.Execute(); } }
各状态类
public class StartingState : IOperationState { public int ExecuteOperation(OperatingClass operatingClass) { // Do something... operatingClass.OperationState = new MiddleState(); return operatingClass.Execute(); } } public class MiddleState : IOperationState { public int ExecuteOperation(OperatingClass operatingClass) { //Do something with the value... let's supose the result is 123, but it does not matter rn; operatingClass.value = 123; //Here is the problem: FinalState needs the PersistenceService, who //receives a injected class to acess the database; operatingClass.OperationState = new FinalState(); //I want to execute it and return the sucess or failure of the persistence. return operatingClass.Execute(); } } public class FinalState : IOperationState { private readonly IPersistenceService PersistenceService; public FinalState(IPersistenceService persistenceService) { PersistenceService = persistenceService; } public int ExecuteOperation(OperatingClass operatingClass) { return PersistenceService.PersistData(operatingClass.id, operatingClass.value) ? 200 : 503; } }
补充:Startup配置
public void ConfigureServices(IServiceCollection services) { services.AddTransient<IPersistenceService, PersistenceService>(); // Irrelevant configurations for the question. services.AddControllers(); }
解决方案
方法1:通过依赖注入容器获取服务(快速调整)
让MainService注入IServiceProvider,将服务传递给OperatingClass,再由状态类调用:
修改MainService:
public class MainService { private readonly IServiceProvider _serviceProvider; public MainService(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; } public int ExecuteFullOperation(int id) { var operatingClass = new OperatingClass(id, _serviceProvider); return operatingClass.Execute(); } }
修改OperatingClass:
public class OperatingClass { public IOperationState OperationState { get; set; } public int id { get; set; } public double value { get; set; } private readonly IServiceProvider _serviceProvider; public OperatingClass(int id, IServiceProvider serviceProvider) { this.id = id; value = 0; _serviceProvider = serviceProvider; OperationState = new StartingState(); } public int Execute() { return OperationState.ExecuteOperation(this); } // 提供获取服务的方法给状态类 public T GetService<T>() where T : notnull { return _serviceProvider.GetRequiredService<T>(); } }
修改MiddleState:
public class MiddleState : IOperationState { public int ExecuteOperation(OperatingClass operatingClass) { operatingClass.value = 123; // 从OperatingClass获取服务实例化FinalState var persistenceService = operatingClass.GetService<IPersistenceService>(); operatingClass.OperationState = new FinalState(persistenceService); return operatingClass.Execute(); } }
方法2:用状态工厂管理实例(更优雅)
将所有状态类注册到DI容器,通过工厂模式创建状态实例:
- 注册状态类到容器:
public void ConfigureServices(IServiceCollection services) { services.AddTransient<IPersistenceService, PersistenceService>(); services.AddTransient<StartingState>(); services.AddTransient<MiddleState>(); services.AddTransient<FinalState>(); services.AddControllers(); }
- 创建状态工厂:
public interface IStateFactory { T CreateState<T>() where T : IOperationState; } public class StateFactory : IStateFactory { private readonly IServiceProvider _serviceProvider; public StateFactory(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; } public T CreateState<T>() where T : IOperationState { return _serviceProvider.GetRequiredService<T>(); } }
- 注册工厂:
services.AddTransient<IStateFactory, StateFactory>();
- 修改
OperatingClass:
public class OperatingClass { public IOperationState OperationState { get; set; } public int id { get; set; } public double value { get; set; } private readonly IStateFactory _stateFactory; public OperatingClass(int id, IStateFactory stateFactory) { this.id = id; value = 0; _stateFactory = stateFactory; OperationState = _stateFactory.CreateState<StartingState>(); } public int Execute() { return OperationState.ExecuteOperation(this); } public T GetState<T>() where T : IOperationState { return _stateFactory.CreateState<T>(); } }
- 修改
MiddleState:
public class MiddleState : IOperationState { public int ExecuteOperation(OperatingClass operatingClass) { operatingClass.value = 123; operatingClass.OperationState = operatingClass.GetState<FinalState>(); return operatingClass.Execute(); } }
方法3:直接传递依赖(最小改动)
在MainService注入IPersistenceService,直接传递给OperatingClass,再传给FinalState:
修改MainService:
public class MainService { private readonly IPersistenceService _persistenceService; public MainService(IPersistenceService persistenceService) { _persistenceService = persistenceService; } public int ExecuteFullOperation(int id) { var operatingClass = new OperatingClass(id, _persistenceService); return operatingClass.Execute(); } }
修改OperatingClass:
public class OperatingClass { public IOperationState OperationState { get; set; } public int id { get; set; } public double value { get; set; } public IPersistenceService PersistenceService { get; } public OperatingClass(int id, IPersistenceService persistenceService) { this.id = id; value = 0; PersistenceService = persistenceService; OperationState = new StartingState(); } public int Execute() { return OperationState.ExecuteOperation(this); } }
修改MiddleState:
public class MiddleState : IOperationState { public int ExecuteOperation(OperatingClass operatingClass) { operatingClass.value = 123; operatingClass.OperationState = new FinalState(operatingClass.PersistenceService); return operatingClass.Execute(); } }
内容的提问来源于stack exchange,提问作者VieiraHeloisa
相关产品推荐
相关产品推荐

