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



我正在学习。net中的设计模式,目前我正在尝试实现状态模式。但是今天我遇到了一个问题,我不知道如何解决这个问题。

我有一些状态类,它们都实现状态接口。最后的状态之一应该通过. net API Startup类注入的服务连接到数据库,以持久化数据并完成该过程。

问题是……由于需要在最终状态中进行依赖项注入,因此无法实例化此状态对象以进展到这一点。我不知道该如何继续。我不知道是我使用了错误的模式,还是在这个模式中使用依赖注入是问题所在。我不能给出这个问题的所有细节,因为我的研究项目现在有点乱,所以我做了一个快速的模拟我试图在我的应用程序中构建的结构。

state接口和执行状态行为的operingclass:

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

Main Service:是我的控制器接收到API Post Method后调用的服务:

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

附加信息:我把PersistenceService作为一个瞬态注入到Startup.cs中(我现在不知道如何以另一种方式注入)

public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IPersistenceService, PersistenceService>();
// Irrelevant configurations for the question.
services.AddControllers();
}
如果可以的话,请帮帮我。我一个人想弄清楚这件事很难。感谢您的耐心阅读。
<代码>

首先,我们需要一些简单的工厂,它将按类型提供所有必需的依赖项。让我们为状态创建类型:

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

我们的状态是这样的:

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

StateFactory应该是这样的:

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:

公共类operationclass{public IOperationState OperationState {get;设置;}Public int id {get;设置;}公共双精度值{get;设置;}

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

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

PP_16

最新更新