Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ## Я хочу добавить новое состояние, что мне нужно сделать?
- Для того, чтобы добавить новое состояние, нужно выполнить 2 шага:
- 1. В папке `Features` создать папку с именем состояния. В нашем случае это `ApplicationConsideration`. В папке создать класс `ApplicationConsiderationState` и выполнить наследование от класса `ProcedureState<TState>`.
- ```csharp
- /// <inheritdoc />
- public sealed class ApplicationConsiderationState : ProcedureState<ApplicationConsiderationState>
- {
- /// <inheritdoc />
- public ApplicationConsiderationState(
- IStateDescriptor<Procedure, ApplicationConsiderationState> descriptor,
- IStateActionExecutionProvider<Procedure, ApplicationConsiderationState> provider)
- : base(descriptor, provider)
- { }
- }
- ```
- 2. Зарегистрировать состояние в контейнере зависимостей.
- ```csharp
- container.AddStateMachine<Procedure>(assemblies)
- .AddState<ApplicationConsiderationState>();
- ```
- ## Я хочу добавить новое действие, что мне нужно сделать?
- Для того, чтобы добавить новое действие, нужно выполнить 3 шага:
- 1. Если действие общее для нескольких состояний, тогда в папке c проектом создать (если еще не создана) папку `StateActions`. В этой папке создать класс действия (например, `SchedulerStateAction`). Если действие относиться только к одному состоянию, тогда необходимо в папке с классом состояния создать (если еще не создана) папку `StateActions`. Если действие сложное, то есть может содержать дополнительные данные или результат, следует создать отделную папку с названием действия. В папке разместить само действие, а также `ActionData` и `ActionResult`.
- ### PublishProtocolStateAction.cs
- ```csharp
- using System;
- /// <summary>
- /// Действие публикации протокола.
- /// </summary>
- public sealed class PublishProtocolStateAction : StateAction<PublishProtocolStateActionData, PublishProtocolStateActionResult>
- {
- /// <summary>
- /// Инициализирует экземпляр <see cref="PublishProtocolStateAction" />.
- /// </summary>
- public PublishProtocolStateAction(PublishProtocolStateActionData data)
- : base(data, nameof(PublishProtocolStateAction), DateTime.UtcNow)
- { }
- /// <summary>
- /// Инициализирует экземпляр <see cref="PublishProtocolStateAction" />.
- /// </summary>
- public PublishProtocolStateAction(PublishProtocolStateActionData data, string name, DateTime date)
- : base(data, name, date)
- { }
- }
- ```
- ### PublishProtocolStateActionData.cs
- ```csharp
- /// <summary>
- /// Данные для выполнения действия публикации протокола.
- /// </summary>
- public sealed class PublishProtocolStateActionData
- {
- /// <summary>
- /// Идентификатор протокола.
- /// </summary>
- public int ProtocolId { get; set; } = 666;
- }
- ```
- ### PublishProtocolStateActionResult.cs
- ```csharp
- using System.Collections.Generic;
- /// <summary>
- /// Результат выполнения действия публикации протокола.
- /// </summary>
- public sealed class PublishProtocolStateActionResult
- {
- /// <summary>
- /// Саги на блокировку денежных средств.
- /// </summary>
- public List<object> BlockMoneySagas = new List<object>();
- }
- ```
- 2. Связать добавленное действие с нужными состояниями. Для этого нужно добавить атрибут `StateAction` над классом нужного состояния и передать в него тип нужного действия.
- ```csharp
- /// <inheritdoc />
- [StateAction(typeof(PublishProtocolStateAction))] // <-- HERE
- public sealed class ApplicationWinnerDeterminationState : ProcedureState<ApplicationWinnerDeterminationState>
- {
- /// <inheritdoc />
- public ApplicationWinnerDeterminationState(
- IStateDescriptor<Procedure, ApplicationWinnerDeterminationState> descriptor,
- IStateActionExecutionProvider<Procedure, ApplicationWinnerDeterminationState> provider)
- : base(descriptor, provider)
- { }
- }
- ```
- 3. Добавить обработчик действия для конкретного состояния. Почему для конкретного? Потому что некоторые (общие) действия могут использоваться из разных состояний, но логика у них должна быть разная. Для этого нужно в папке, где находится состояние, добавить еще папку `StateActionExecutors`. А в ней уже создать обработчик (средство для выполнения действия). **Регистрировать обработчики явным образом не нужно.**
- ```csharp
- using System;
- using Models;
- using StateActions.PublishProtocol;
- /// <inheritdoc />
- public sealed class ApplicationWinnerDeterminationPublishProtocolActionExecutor : ProcedureStateActionExecutor<ApplicationWinnerDeterminationState, PublishProtocolStateAction>
- {
- /// <inheritdoc />
- protected override void BeforeExecute()
- {
- if (ExecutionContext.GetProcedureState() != ProcedureStateEnum.ApplicationWinnerDetermination)
- throw new StateMachineException("Процедура находиться в статусе, непригодном для выполнения действия.");
- }
- /// <inheritdoc />
- protected override void Execute()
- {
- Console.WriteLine($"Идентификатор публикуемого протокол: {ExecutionContext.GetProtocolId()}.");
- // Add few block money sagas.
- ExecutionContext.AddBlockMoneySaga(new { Id = 1 });
- ExecutionContext.AddBlockMoneySaga(new { Id = 2 });
- ExecutionContext.AddBlockMoneySaga(new { Id = 3 });
- ExecutionContext.SetProcedureState(ProcedureStateEnum.ContractConclusion);
- }
- /// <inheritdoc />
- protected override void AfterExecute()
- {
- Console.WriteLine($"Протокол с идентификатором {ExecutionContext.GetProtocolId()} опубликован.");
- }
- }
- ```
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement