SkillAgentSearch skills...

Foodtruacker

Implementation of DDD, CQRS and Event Sourcing

Install / Use

/learn @hiiammalte/Foodtruacker

README

foodtruacker - Implementation of DDD, CQRS and Event Sourcing

This event-driven project utilizes priciples, frameworks and achitectures — all centered around the idea of enhancing maintainability when dealing with systems reflecting complex business domains. The application's Web API is build upon Microsoft's ASP.NET Core framework and implements Domain-driven Design, as well as the CQRS and Event Sourcing patterns. A fictional business case lays the foundation of this project and is the result of an event storming workshop.

Please note: The fictional business domain introduced to this project is heavily simplified and should only be seen as a provider of relatable use cases.

Motivation

Since it is not always best to use CRUD-operations and POCO-objects in projects with rather complex business domains, I decided to create this project as a practical implemention of my research on — and interest in — the Domain-driven Design (DDD) approach of developing software.

Since the fictional business case intoduced to this project is heavily event-driven, I decided to also implement the CQRS and Event Sourcing patterns. Both caught my attention while doing the research for this project and go well together with DDD.

Features

  • ASP.NET Core 9.0 Web API application
  • Clean Architecture implementation with applying SOLID principles
  • Domain-driven Design (DDD)
  • xUnit-based Test-driven Design (TDD)
  • Hexagonal architecture a.k.a. Ports & Adapters (Domain, Application and Framework Layers)
  • CQRS implementation on Commands, Queries and Projections
  • MediatR implementation (Request- and Notification-Handling, Pipeline-Behaviour for Logging, Metrics and Authentication)
  • Swagger Open API endpoint
  • Dockerfile and Docker Compose (YAML) file for environmental setup
  • EventStoreDB Repository and custom Client for storing of events
  • MongoDB Repository for performance-optimized querying
  • Authentication Service based on ASP.NET Core Idenity
  • Email Service for account verification
  • Shared Kernel class library implementation for DDD & Event Sourcing

Overview

This project consists of one executable Web API application and several functional components, each provided via class libraries. The code is organized by namespaces. In ASP.NET Core applications created in Visual Studio the namespaces, by default, are automatically created from the projects' folder structure. See the below diagram for a grasp overview of the folder (and namespace) structure of this project:

.
├── foodtruacker.AcceptanceTests
│   ├── BoundedContexts                     # Tests - organized by bounded context (see Domain-driven Design)
│   │   ├── UserAccountManagement           # All tests related to user account managment
│   │   └── ...
│   └── Framework                           # XUnit- and Moq-based test setup based on given-when-then priciple
├── foodtruacker.API
│   ├── Controllers                         # API Endpoints - request handlers are invoking MediatR Commands and Queries
│   ├── DTOs                                # DTOs to be used in API requests to manipulate data (commands)
│   ├── Extensions                          # Bundled services to be registered in ConfigureServices() function in Startup.cs file 
│   ├── Middleware                          # Middleware functions to be injected into Configure() pipeline in Startup.cs file
│   ├── appsettings.json                    # Application configuration file used to store configuration settings such as database connections strings
│   ├── Dockerfile                          # Instructions for building a Docker image from the foodtruacker application
│   ├── Program.cs                          # Entry point of the application
│   └── Startup.cs                          # Configuration class used for registering services and injecting middleware into the application pipeline
├── foodtruacker.Application
│   ├── BoundedContexts                     # CQRS logic - organized by bounded context (see Domain-driven Design)
│   │   ├── UserAccountManagement           # All classes and functions related to user account managment
│   │   │   ├── Commands                    # MediatR based Commands and Command-handlers - communicating with Event Sourcing database
│   │   │   ├── EventHandlers               # MediatR based Event-handlers for Notifications - used for triggering external services
│   │   │   ├── Projections                 # MediatR based Event-handlers for Notifications - used for updating Query database
│   │   │   ├── Queries                     # MediatR based Queries and Query-handlers - communicating with Query database
│   │   │   └── QueryObjects                # Response objects used in API requests to read data (queries)
│   │   └── ...
│   ├── Pipelines                           # MediatR pipeline behaviours (middleware)
│   └── Results                             # Wrapper classes and error definitions used for handling commands
├── foodtruacker.Authentication
│   ├── Configuration                       # POCOs for roles, JWT, database communication
│   ├── Entities                            # User and Role entities required by Identity ASP.NET Core
│   ├── Exceptions                          # Exceptions related to authentication
│   ├── Migrations                          # Entity Framework migration scripts for using Identity ASP.NET Core with MySQL-database
│   ├── Repository                          # DbContext, Repository Interface and corresponding service for Identity ASP.NET Core 
│   └── Services                            # Interfaces and corresponding services related to authentication (e.g. JWT)
├── foodtruacker.Domain
│   ├── BoundedContexts                     # Domain objects - organized by bounded context (see Domain-driven Design)
│   │   ├── UserAccountManagement           # All objects and exceptions related to user account managment
│   │   │   ├── Aggregates                  # Aggregates with internal business logic (see Domain-driven Design)
│   │   │   ├── Events                      # Domain-related events (see Event Sourcing)
│   │   │   ├── Exceptions                  # Exceptions related to business logic
│   │   │   └── ValueObjects                # Value Objects with internal business logic (see Domain-driven Design)
│   │   └── ...
│   └── Exceptions                          # General domain and business logic exceptions
├── foodtruacker.EmailService
│   └── Services                            # Interface and corresponding service related to sending emails (dummy - writes output into logs)
├── foodtruacker.EventSourcingRepository
│   ├── Client                              # Interface and corresponding service for reading and appending events from/to EventStoreDB
│   ├── Configuration                       # POCO for database communication
│   └── Repository                          # Repository interface and corresponding service for custom Event Sourcing Client (see above)
├── foodtruacker.QueryRepository
│   ├── Configuration                       # POCO for database communication
│   └── Repository                          # Repository interface and corresponding service for MongoDB
└── foodtruacker.SharedKernel
    ├── IAggregateRoot.cs                   # Interface for base functionality of an aggregate - used for recreation of aggregates from EventStoreDB (via reflection)
    ├── AggregateRoot.cs                    # Abstract class providing base functionality of an aggregate - inherits IAggregateRoot, is derived by all aggregates
    ├── IDomainEvent.cs                     # Interface for base functionality of an domain-related event - used for recreation of events stored in EventStoreDB (via reflection)
    ├── DomainEvent.cs                      # Abstract class providing base functionality of an domain-related event - inherits IDomainEvent, is derived by all domain-related events
    ├── IValueObject.cs                     # Interface for base functionality of a value object (see Domain-driven Design)
    ├── ValueObject.cs                      # Abstract class providing functionality for comparing value objects - inherits IValueObjects, is derived by all value objects
    └── ...

Introduction

Event Storming

A flexible workshop format for collaborative exploration of complex business domains, invented by Alberto Brandolini. It is an extremely lightweight methodology for quickly improving, envisioning, exploring and designing business flows and processes within your organization.

The workshop consists of a group of people with different expertise using colored sticky notes to collaboratively layout relevant business processes. It is mandatory for an EventStorming workshop to both have the right people present and to have enough surface area to place the sticky notes on. Required people typically include those who know the questions to ask (typically developers) and those who know the answers (domain experts, product owners).

The aim of this workshop is to have its participants learn from each other, reveal and refute misconceptions and, e.g. in this GitHub project, do the groundwork for the development of an event based software solution reflecting a correlating business domain.

Event Storming Illustration

Domain-driven Design (DDD)

An approach to software development that centers the development on programming a domain model that has a rich understanding of the processes and rules of a correlating business domain. The term „Domain-driven Design“ was coined by Eric Evans in his book of the same title. DDD aims to ease

View on GitHub
GitHub Stars67
CategoryDevelopment
Updated7d ago
Forks9

Languages

C#

Security Score

100/100

Audited on Mar 22, 2026

No findings