Example #1
0
        public bool IsMovementPossible(Money money, CreditTransactionType creditTransactionType)
        {
            Money currentBalance = GetBalance();

            Money balanceAfterMovement = new Transaction(money, creditTransactionType).GetBalanceAfterPerformed(currentBalance);

            return(balanceAfterMovement.Amount >= 0);
        }
Example #2
0
        public void MakeMovement(Money money, CreditTransactionType creditTransactionType)
        {
            if (!IsMovementPossible(money, creditTransactionType))
            {
                throw new NegativeBalanceReachedException("Balance would be negative after this transaction.");
            }

            _executedTransactions.Add(new ExecutedTransaction(money, creditTransactionType));
        }
Example #3
0
 public Transaction(Money money, CreditTransactionType creditTransactionType)
 {
     Money = money;
     CreditTransactionType = creditTransactionType;
 }
Example #4
0
 public ExecutedTransaction(Money money, CreditTransactionType creditTransactionType) : base(money, creditTransactionType)
 {
     MovementDate = DateTime.UtcNow;
 }
        public Task <TransactionAttempt> ExecuteTransaction(Guid transactionIdentifier, Player player, Money money, CreditTransactionType creditTransactionType)
        {
            bool             isMovementPossible = player.Wallet.IsMovementPossible(money, creditTransactionType);
            TransactionState transactionResult;

            if (isMovementPossible)
            {
                player.Wallet.MakeMovement(money, creditTransactionType);
                transactionResult = TransactionState.Accepted;
            }
            else
            {
                transactionResult = TransactionState.Rejected;
            }

            return(Task.FromResult(new TransactionAttempt(transactionIdentifier, transactionResult)));
        }
        public async Task <Result <TransactionAttempt> > ExecuteTransaction(Guid transactionIdentifier, Player player, Money money, CreditTransactionType creditTransactionType)
        {
            bool transactionShouldBeProcessed = _transactionTasksByIdentifier.TryAdd(transactionIdentifier, new TaskCompletionSource <Result <TransactionAttempt> >());

            TaskCompletionSource <Result <TransactionAttempt> > transactionInProgress = _transactionTasksByIdentifier[transactionIdentifier];

            if (!transactionShouldBeProcessed)
            {
                return(await transactionInProgress.Task);
            }

            Result <TransactionAttempt> transaction = null;

            try
            {
                transaction = await _oneTransactionPerPlayerChecker.ExecuteTransaction(transactionIdentifier, player, money, creditTransactionType);
            }
            catch (Exception ex)
            {
                _transactionTasksByIdentifier.TryRemove(transactionIdentifier, out _);
                transaction = Result.Failure <TransactionAttempt>(ex.Message);
            }
            finally
            {
                transactionInProgress.SetResult(transaction);
            }

            return(transaction);
        }
        public async Task <TransactionAttempt> ExecuteTransaction(Guid transactionIdentifier, Player player, Money money, CreditTransactionType creditTransactionType)
        {
            _transactionQueuePerPlayer.TryAdd(player.Identifier, new SemaphoreSlim(MaxNumberOfTransactionsPerPlayer, MaxNumberOfTransactionsPerPlayer));

            SemaphoreSlim semaphoreForTransactionProcessingPerPlayer = _transactionQueuePerPlayer[player.Identifier];

            await semaphoreForTransactionProcessingPerPlayer.WaitAsync();

            try
            {
                return(await _transactionDomainLogicExecutor.ExecuteTransaction(transactionIdentifier, player, money, creditTransactionType));
            }
            finally
            {
                semaphoreForTransactionProcessingPerPlayer.Release();
            }
        }