-
Notifications
You must be signed in to change notification settings - Fork 60
/
AccountProcess.cs
36 lines (30 loc) · 1.16 KB
/
AccountProcess.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
using Boc.Commands;
using LaYumba.Functional;
using static LaYumba.Functional.F;
using System;
using System.Threading.Tasks;
using Boc.Chapter13.Domain;
using Boc.Domain.Events;
using Unit = System.ValueTuple;
namespace Boc.Chapter19
{
using Result = Validation<(Event Event, AccountState NewState)>;
public class AccountProcess
{
Agent<Command, Result> agent;
public AccountProcess(AccountState initialState, Func<Event, Task<Unit>> saveAndPublish)
=> agent = Agent.Start(initialState
, async (AccountState state, Command cmd) =>
{
Result result = cmd switch
{
MakeTransfer transfer => state.Debit(transfer),
FreezeAccount freeze => state.Freeze(freeze),
};
await result.Traverse(tpl => saveAndPublish(tpl.Event)); // persist within block, so that the agent doesn't process new messages in a non-persisted state
var newState = result.Map(tpl => tpl.NewState).GetOrElse(state);
return (newState, result);
});
public Task<Result> Handle(Command cmd) => agent.Tell(cmd);
}
}