.NET -可以将DI与状态模式一起使用吗?

4uqofj5v  于 2022-11-19  发布在  .NET
关注(0)|答案(1)|浏览(129)

我正在学习.NET中的设计模式,目前我正在尝试实现状态模式。但是今天我遇到了一个问题,我不知道如何解决这个问题。
我有一些状态类,它们都实现了状态接口。最后的状态之一应该通过.NET API Startup类注入的服务连接到数据库,以持久化数据并完成该过程。
问题是...因为依赖注入我需要处于最终状态,我无法示例化此状态对象以前进到这一点。我不知道如何从那里继续。我不知道是我使用了错误的模式还是在此模式中使用了依赖注入。我不能给予问题的所有细节,因为我的研究“的项目目前有点混乱,所以我快速模拟了一下我试图在应用程序中构建的结构。
状态接口和将执行状态行为的OperatingClass:
第一个
主要服务:是我的控制器在接收API Post方法后调用的服务:

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();
        }
    }

表示状态并执行相应操作的类:
第一个
其他信息:我将PersistenceService作为Transient注入Startup.cs中(此时我不知道如何以其他方式进行)。

public void ConfigureServices(IServiceCollection services)
        {
            services.AddTransient<IPersistenceService, PersistenceService>();
            // Irrelevant configurations for the question.
            services.AddControllers();
        }

如果可以的话,请帮助我。我自己很难弄清楚。谢谢你的耐心和你的时间阅读它。

sc4hvdpw

sc4hvdpw1#

首先,我们需要一些简单的工厂,它将按照类型提供所有必要的依赖关系。

public enum StateType
{
    Start,
    Middle,
    Final
}

和简单的工厂:

public class StateFactory
{
    private Dictionary<StateType, IOperationState> _stateByType;

    // you can inject these dependencies through DI like that:
    // public StateFactory(StartingState startingState, 
    //     MiddleState middleState, FinalState finalState, 
    //     PersistenceService persistenceService)
    public StateFactory()
    {
        _stateByType = new Dictionary<StateType, IOperationState>()
        {
            { StateType.Start, new StartingState(this) },
            { StateType.Middle, new MiddleState(this) },
            { StateType.Final, new FinalState(new PersistenceService()) }
        };
    }

    public IOperationState GetByType(StateType stateType) => 
        _stateByType[stateType];
}

然后我们应该注册所有依赖项:

public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<IPersistenceService, PersistenceService>();
    
    services.AddTransient<StartingState>();
    services.AddTransient<MiddleState>();
    services.AddTransient<FinalState>();
    
    services.AddTransient<MainService>();
    services.AddTransient<OperatingClass>();
    services.AddTransient<PersistenceService>();
    services.AddTransient<StateFactory>();

}

我们的状态如下所示:

public class StartingState : IOperationState
{
    private StateFactory _factory;

    public StartingState(StateFactory stateFactory)
    {
        _factory = stateFactory;
    }

    public int ExecuteOperation(OperatingClass operatingClass)
    {
        // Do something...
        // operatingClass.OperationState = new MiddleState();
        operatingClass.OperationState = _factory.GetByType(StateType.Middle);
        return operatingClass.Execute();
    }
}

MiddleState看起来像这样:

public class MiddleState : IOperationState
{
    private StateFactory _factory;

    public MiddleState(StateFactory stateFactory)
    {
        _factory = stateFactory;
    }

    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 = _factory.GetByType(StateType.Final);

        //I want to execute it and return the sucess or failure of the persistence.
        return operatingClass.Execute();
    }
}

Final state应该如下所示:

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;
    }
}

其他类(如OperatingClass)也将使用StateFactory
在此基础上,给出了一个基于类的操作系统的设计方法。{1}获取一个公共的整数id {2}{3}。{4} set; }公共双精度值{ get;设置; }

public OperatingClass(int id, StateFactory stateFactory)  //constructor
    {
        this.id = id;
        value = 0;
        // OperationState = new StartingState();
        OperationState = stateFactory.GetByType(StateType.Start);
    }

    public int Execute()
    {
        return OperationState.ExecuteOperation(this);
    }
}

并且有必要创建PersistenceService的具体示例:

public interface IPersistenceService
{
    bool PersistData(int id, double value);
}

public class PersistenceService : IPersistenceService
{
    public bool PersistData(int id, double value)
    {
        throw new NotImplementedException();
    }
}

相关问题