示例#1
0
        public IEnumerable <AggregateEvent> TransferMoney(TransferMoneyCommand command)
        {
            if (this.CurrentBalance < command.Amount)
            {
                throw new InvalidOperationException($"Account {AccountNumber} does not have enough balance to execute the transaction.");
            }
            if (this.AccountState != AccountState.Created)
            {
                throw new InvalidOperationException($"Account {AccountNumber} is not available.");
            }

            var destinationAccountEvents = this.EventStore.GetAggregateEvents(CreateAggregateId(command.DestinationAccountNumber));
            var destinationAccount       = new Account(this.EventStore, destinationAccountEvents);

            if (destinationAccount.AccountState != AccountState.Created)
            {
                throw new InvalidOperationException($"Account {destinationAccount.AccountNumber} is not available.");
            }

            var aggregateEvent = new BalanceIncreased(command.DestinationAccountNumber, ++destinationAccount.SequenceNumber, command.Amount);

            Handle(aggregateEvent);

            return(new AggregateEvent[]
            {
                aggregateEvent,
                new BalanceDecreased(command.SourceAccountNumber, ++this.SequenceNumber, command.Amount)
            });
        }
        public async Task TransferMoneyAsync(TransferMoneyCommand command)
        {
            var sourceAccount = BuildAccountFromDomainEvents(command.SourceAccountNumber);
            var events        = sourceAccount.TransferMoney(command);

            await this.EventStore.AddEventsAsync(events);
        }
示例#3
0
        public ActionResult TransferMoney(TransferMoneyCommand transferMoney)
        {
            var fromAccountBalance = this.accountRepository.GetBalance(transferMoney.FromAccountId);
            var toAccountBalance   = this.accountRepository.GetBalance(transferMoney.ToAccountId);

            if (fromAccountBalance < transferMoney.Amount)
            {
                throw new InsufficientFundsException();
            }

            this.accountRepository.UpdateBalance(transferMoney.FromAccountId, fromAccountBalance - transferMoney.Amount);
            this.accountRepository.UpdateBalance(transferMoney.ToAccountId, toAccountBalance + transferMoney.Amount);

            return(this.RedirectToAction("TransferMoney"));
        }
        public ActionResult TransferMoney(TransferMoneyCommand transferMoney)
        {
            var fromAccount = accounts.Get(transferMoney.FromAccountId);
            var toAccount   = accounts.Get(transferMoney.ToAccountId);

            if (fromAccount.CurrentBalance < transferMoney.Amount)
            {
                throw new InsufficientFundsException();
            }

            fromAccount.CurrentBalance = fromAccount.CurrentBalance - transferMoney.Amount;
            toAccount.CurrentBalance   = toAccount.CurrentBalance + transferMoney.Amount;

            return(this.RedirectToAction("TransferMoney"));
        }
示例#5
0
        public bool Execute(TransferMoneyCommand command)
        {
            var balanceSpec         = new EnoughBalanceAmountSpecification();
            var minimumTransferSpec = new MinimumTransferAmountSpecification();

            var andSpec = balanceSpec.And(minimumTransferSpec);

            if (andSpec.IsSatisfiedBy(State))
            {
                var sentEvent = new MoneySentEvent(command.Transaction);
                var feeEvent  = new FeesDeductedEvent(new Money(0.25m));

                EmitAll(sentEvent, feeEvent);
            }

            return(true);
        }
示例#6
0
        public static async Task Main(string[] args)
        {
            //initialize actor system
            CreateActorSystem();

            //create send receiver identifiers
            var senderId   = AccountId.New;
            var receiverId = AccountId.New;

            //create mock opening balances
            var senderOpeningBalance   = new Money(509.23m);
            var receiverOpeningBalance = new Money(30.45m);

            //create commands for opening the sender and receiver accounts
            var openSenderAccountCommand   = new OpenNewAccountCommand(senderId, senderOpeningBalance);
            var openReceiverAccountCommand = new OpenNewAccountCommand(receiverId, receiverOpeningBalance);

            //send the command to be handled by the account aggregate
            AccountManager.Tell(openReceiverAccountCommand);
            AccountManager.Tell(openSenderAccountCommand);

            //create command to initiate money transfer
            var amountToSend         = new Money(125.23m);
            var transaction          = new Transaction(senderId, receiverId, amountToSend);
            var transferMoneyCommand = new TransferMoneyCommand(senderId, transaction);

            //send the command to initiate the money transfer
            AccountManager.Tell(transferMoneyCommand);

            //fake 'wait' to let the saga process the chain of events
            await Task.Delay(TimeSpan.FromSeconds(1));

            Console.WriteLine("Walkthrough operations complete.\n\n");
            Console.WriteLine("Press Enter to get the revenue:");

            Console.ReadLine();

            //get the revenue stored in the repository
            var revenue = RevenueRepository.Ask <RevenueReadModel>(new GetRevenueQuery(), TimeSpan.FromMilliseconds(500)).Result;

            //print the results
            Console.WriteLine($"The Revenue is: {revenue.Revenue.Value}.");
            Console.WriteLine($"From: {revenue.Transactions} transaction(s).");

            Console.ReadLine();
        }
示例#7
0
        public void ExampleCommandHandler()
        {
            /* *************************************************************
            * This test demonstrates the action that might be taken in the
            * TransferMoneyCommand command handler
            * *************************************************************/

            // arrange
            var repository = GetFakeRepo();

            // simulating a command coming in to transfer from account A to B
            TransferMoneyCommand command = GetTransferRequest();

            // act
            var source      = repository.Get(command.SourceAccountId);
            var destination = repository.Get(command.DestinationAccount);
            var amount      = new Money(command.Amount);

            source.TransferOut(amount, destination, DateTimeOffset.UtcNow);
            repository.Save(source, destination);
        }
 public async Task TransferMoney([FromBody] TransferMoneyCommand command)
 {
     await this.AccountCommands.TransferMoneyAsync(command);
 }
示例#9
0
        public async Task TransferMoney([FromBody] TransferMoneyDto request)
        {
            var command = new TransferMoneyCommand(request.SourceAccountNumber, request.DestinationAccountNumber, request.Amount);

            await this.AccountCommands.TransferMoneyAsync(command);
        }
        public ActionResult Transfer(Guid? SourceAccount, Guid? SinkAccount, decimal? amount)
        {
            var transferMoneyCommand = new TransferMoneyCommand { SourceAccountId = SourceAccount.Value, SinkAccountId = SinkAccount.Value, Amount = amount.Value };

            _cmdBus.Send(transferMoneyCommand);

            return RedirectToAction("Success");
        }