using CsharpFp3.Domain; using CsharpFp3.Infrastructure; using CsharpFp3.Library; using static CsharpFp3.Library.ResultModule; namespace CsharpFp3.Application; using CreateResultType = Result>, AppError>; public abstract record AppError { public sealed record RepositoryCreationFailed(string Message) : AppError; public sealed record InnerAccountError(AccountError InnerError) : AppError; } public static class AccountApplication { public static CreateResultType CreateWithdrawMoney(Repository repo) => Ok( // types needed in this lambda, otherwise c# doesn't love us (Guid accountId, decimal amount) => repo.LoadAccount(accountId) .Log("App load", "Account loaded") .Log("App exec wdrwl", $"[App] Executing withdrawal of {amount:0.00}...") .Bind(account => AccountDomain.Withdraw(account, new Money(amount))) .Log( "App wdrwl done", a => $"Withdrawal applied. New balance: {a.Balance.Amount:0.00}" ) .Bind(repo.SaveAccount) .Log("App acc svd", "[App] Account persisted.") ); }