using System.Collections.Immutable; using CsharpEs.Domain; using CsharpEs.Infrastructure; using CsharpEs.Library; public abstract record DemoError { public sealed record Account(AccountError Error) : DemoError; public sealed record ReadModel(ReadModelError Error) : DemoError; } public class Program { private static Guid accountId; private static ImmutableList demoCommands = ImmutableList.Empty; static Program() { accountId = Guid.NewGuid(); demoCommands = demoCommands.AddRange([ new AccountCommand.OpenAccount(accountId, new Money(-200m)), // new AccountCommand.OpenAccount(accountId, new Money(200m)), new AccountCommand.WithdrawMoney(accountId, new Money(100m)), new AccountCommand.WithdrawMoney(accountId, new Money(200m)), new AccountCommand.DepositMoney(accountId, new Money(500m)), ]); } static ImmutableList eventStore = ImmutableList.Empty; static Result ApplyEvent( AccountBalanceReadModel balanceProjection, AccountState? state, AccountEvent @event ) { eventStore = eventStore.Add(@event); Logging.Output( "ae", $"Applying event {Logging.Format(@event)} to state {Logging.Format(state)}" ); return AccountDecider .Evolve(state, @event) .MapError(e => (DemoError)new DemoError.Account(e)) .Bind(newState => balanceProjection .Project(@event) .MapError(e => (DemoError)new DemoError.ReadModel(e)) .Log("ae ad", "Account details") .Map(_ => newState) ) .Log("ae", $"Applied and projected {Logging.Format(@event)}"); } public static void Main(string[] args) { Logging.Output("csharp-es", "Starting money handling demo..."); AccountBalanceReadModelModule .Create() .MapError(e => (DemoError)new DemoError.ReadModel(e)) .Bind(readModel => demoCommands .Aggregate( Result.Ok(null), (stateResult, command) => stateResult.Bind(state => AccountDecider .Decide(state, command) .MapError(e => (DemoError)new DemoError.Account(e)) .Bind(@event => ApplyEvent(readModel, state, @event)) ) ) .Bind(s => readModel .Query() .Log("query", "Read model data") .MapError(e => (DemoError)new DemoError.ReadModel(e)) ) ) .Log("csharp-es done", "Demo completed."); } }