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

.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容器,通过工厂模式创建状态实例:

  1. 注册状态类到容器:
public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<IPersistenceService, PersistenceService>();
    services.AddTransient<StartingState>();
    services.AddTransient<MiddleState>();
    services.AddTransient<FinalState>();
    services.AddControllers();
}
  1. 创建状态工厂:
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>();
    }
}
  1. 注册工厂:
services.AddTransient<IStateFactory, StateFactory>();
  1. 修改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>();
    }
}
  1. 修改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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 10:35:24