Courses/C#/Final Projects/Banking System
    🏦

    Banking System with DDD

    Expert Project — Aggregates, Value Objects, Domain Events, CQRS

    🧠 Project Overview

    Build a banking system using Domain-Driven Design. Practice aggregates that protect business invariants, value objects for type safety, and domain events for decoupled side effects.

    🎯 Requirements

    • • Open Current and Savings accounts with minimum deposit rules
    • • Deposit, withdraw, and transfer between accounts
    • • Transaction history with complete audit trail
    • • Account freezing/closing with state validation
    • • Domain events for notifications and audit logging
    • • Full unit test coverage of domain logic

    Step 1: Aggregate Root

    BankAccount Aggregate

    Aggregate root with factory method, invariant protection, and domain events.

    Try it Yourself »
    C#
    // Domain/Aggregates/BankAccount.cs
    public class BankAccount
    {
        public Guid Id { get; private set; }
        public string OwnerId { get; private set; } = "";
        public string OwnerName { get; private set; } = "";
        public AccountType Type { get; private set; }
        public Money Balance { get; private set; } = new(0, "GBP");
        public AccountStatus Status { get; private set; }
        private readonly List<Transaction> _transactions = new();
        public IReadOnlyCollection<Transaction> Transactions
    ...

    Step 2: Transfer Use Case

    Transfer Funds Handler

    Orchestrate a transfer between two accounts with atomic persistence.

    Try it Yourself »
    C#
    // Application/UseCases/TransferFundsHandler.cs
    public class TransferFundsHandler
    {
        private readonly IAccountRepository _repo;
        private readonly IUnitOfWork _uow;
        private readonly IDomainEventDispatcher _events;
    
        public TransferFundsHandler(IAccountRepository repo,
            IUnitOfWork uow, IDomainEventDispatcher events)
        {
            _repo = repo; _uow = uow; _events = events;
        }
    
        public async Task HandleAsync(TransferCommand cmd)
        {
            var source = await _repo.GetB
    ...

    Step 3: Domain Tests

    BankAccount Unit Tests

    Test all domain rules: deposits, withdrawals, transfers, and freezing.

    Try it Yourself »
    C#
    // Tests/BankAccountTests.cs
    using Xunit;
    
    public class BankAccountTests
    {
        [Fact]
        public void Open_WithSufficientDeposit_CreatesAccount()
        {
            var account = BankAccount.Open("user-1", "Alice",
                AccountType.Current, new Money(500, "GBP"));
    
            Assert.Equal(500m, account.Balance.Amount);
            Assert.Equal(AccountStatus.Active, account.Status);
            Assert.Single(account.Transactions);
        }
    
        [Fact]
        public void Open_SavingsBelowMinimum_Throws()
        {
     
    ...

    Challenge Complete Checklist

    • ☐ All account operations enforce business rules
    • ☐ Transfers are atomic (both accounts updated or neither)
    • ☐ Domain events trigger notifications
    • ☐ Full unit test coverage of aggregate logic
    • ☐ Published to GitHub with architecture diagram
    Back to Projects

    Cookie & Privacy Settings

    We use cookies to improve your experience, analyze traffic, and show personalized ads. You can manage your preferences below.

    By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising. You can customize your preferences or reject non-essential cookies.

    Privacy PolicyTerms of Service