public class Account
{
public Guid Id { get; private set; }
public string Number { get; private set; }
public decimal Balance { get; private set; }
private List<Transaction> _transactions = new();
public IReadOnlyCollection<Transaction> Transactions => _transactions.AsReadOnly();
public Account(string number, decimal initialBalance)
{
Id = Guid.NewGuid();
Number = number;
Balance = initialBalance;
}
public void AddTransaction(Transaction transaction)
{
_transactions.Add(transaction);
Balance += transaction.Amount;
}
}
public class TransactionCreatedEvent : IDomainEvent
{
public Guid AccountId { get; }
public decimal Amount { get; }
public TransactionCreatedEvent(Guid accountId, decimal amount)
{
AccountId = accountId;
Amount = amount;
}
}
public class AccountAggregate : AggregateRoot
{
public Account Account { get; private set; }
public AccountAggregate(Account account)
{
Account = account;
}
}
public interface IAccountRepository
{
Account GetById(Guid id);
void Save(Account account);
}
public class TransactionService
{
private readonly IEventDispatcher _eventDispatcher;
public TransactionService(IEventDispatcher eventDispatcher)
{
_eventDispatcher = eventDispatcher;
}
public void CreateTransaction(Account account, decimal amount)
{
var transaction = new Transaction(amount);
account.AddTransaction(transaction);
_eventDispatcher.Raise(new TransactionCreatedEvent(account.Id, amount));
}
}
public class GetAccountBalanceQueryHandler : IQueryHandler<GetAccountBalanceQuery, decimal>
{
private readonly IAccountRepository _repository;
public GetAccountBalanceQueryHandler(IAccountRepository repository)
{
_repository = repository;
}
public decimal Handle(GetAccountBalanceQuery query)
{
var account = _repository.GetById(query.AccountId);
return account.Balance;
}
}
[Test]
public void AddTransaction_ShouldUpdateBalance()
{
var account = new Account("123456", 1000);
account.AddTransaction(new Transaction(200));
Assert.AreEqual(1200, account.Balance);
}