All Projects → Odonno → cqrs-dotnet-core-example

Odonno / cqrs-dotnet-core-example

Licence: other
A naive introduction to CQRS in C#

Programming Languages

C#
18002 projects

Projects that are alternatives of or similar to cqrs-dotnet-core-example

cash-flow
Application for managing cash flows written in ASP.NET Core 6 and Angular 13 (EF Core, Apollo, GraphQL, CQRS)
Stars: ✭ 27 (-56.45%)
Mutual labels:  cqrs, efcore
incubator-eventmesh
EventMesh is a dynamic event-driven application runtime used to decouple the application and backend middleware layer, which supports a wide range of use cases that encompass complex multi-cloud, widely distributed topologies using diverse technology stacks.
Stars: ✭ 939 (+1414.52%)
Mutual labels:  cqrs
MonolithicArchitecture
This repository presents an approach on how to build an application using Monolithic architecture, ASP.NET Core, EntityFrameworkCore, Identity Server, CQRS, DDD
Stars: ✭ 18 (-70.97%)
Mutual labels:  cqrs
react-evoke
Straightforward action-driven state management for straightforward apps built with Suspense
Stars: ✭ 15 (-75.81%)
Mutual labels:  cqrs
QrF.Core
基于.net core 2.2 的微服务框架
Stars: ✭ 19 (-69.35%)
Mutual labels:  cqrs
commanded-scheduler
Schedule one-off and recurring commands for Commanded CQRS/ES applications
Stars: ✭ 28 (-54.84%)
Mutual labels:  cqrs
stem
Event sourcing framework based on ZIO and pluggable runtime (currently working with Akka cluster)
Stars: ✭ 22 (-64.52%)
Mutual labels:  cqrs
pdo-snapshot-store
PDO Snapshot Store
Stars: ✭ 24 (-61.29%)
Mutual labels:  cqrs
Detached-Mapper
An ORM friendly mapper. Allows saving entire entity graphs. Heavily inspired in GraphDiff and AutoMapper.
Stars: ✭ 89 (+43.55%)
Mutual labels:  efcore
Clean-Architecture-Template
Configurable Clean Architecture template containing the DDD + CQRS approach for .NET Core applications.
Stars: ✭ 14 (-77.42%)
Mutual labels:  cqrs
standard-projections
Standard projections to use with Prooph EventStore
Stars: ✭ 14 (-77.42%)
Mutual labels:  cqrs
micro
Functional prooph for microservices
Stars: ✭ 53 (-14.52%)
Mutual labels:  cqrs
Laraue.EfCoreTriggers
Library for writing triggers in C# using package EFCore
Stars: ✭ 51 (-17.74%)
Mutual labels:  efcore
flighthub
Flight ticket booking system implemented with CQRS and ES.
Stars: ✭ 26 (-58.06%)
Mutual labels:  cqrs
assembler
Functional, type-safe, stateless reactive Java API for efficient implementation of the API Composition Pattern for querying/merging data from multiple datasources/services, with a specific focus on solving the N + 1 query problem
Stars: ✭ 102 (+64.52%)
Mutual labels:  cqrs
VehicleTracker
Vehicle Tracker with Microservice example
Stars: ✭ 70 (+12.9%)
Mutual labels:  cqrs
commander
Build event-driven and event streaming applications with ease
Stars: ✭ 60 (-3.23%)
Mutual labels:  cqrs
payments-DDD-ES-tutorial
This is tutorial project to learn how to connect Symfony4 and docker compose with Domain Driven Design and Event Sourcing
Stars: ✭ 23 (-62.9%)
Mutual labels:  cqrs
food-ordering-demo
Demo application focusing on the Food Ordering domain - Used in our video series
Stars: ✭ 28 (-54.84%)
Mutual labels:  cqrs
nestjs-rest-cqrs-example
Example for Nest.js, MySQL, Redis, REST api, CQRS, DDD
Stars: ✭ 263 (+324.19%)
Mutual labels:  cqrs

A naive introduction to CQRS in C#

A quick intro

CQRS for Command and Query Responsibility Segregation is a pattern used to separate the logic between commands and queries.

Well, if you are used to create HTTP web API, here is the translation:

  • Queries = GET methods
  • Commands = POST/PUT/DELETE methods

CQRS pattern described by Martin Fowler

So why CQRS? Of course, you have the Single Responsibility Principle by design and so you get the ability to design a loosely coupled architecture which has multiple benefits:

  • A clear Read model with a list of queries and domain objects you can use
  • An isolation of each command inside a Write model
  • A simple definition of each query and command
  • Logging queries and commands
  • Being ready to optimize the Read model or the Command model at any time (considering the underlying database)
  • And also writing new queries/commands without breaking previous changes

The naive example

In this example, we will create a Parking system using .NET Core and a single SQL Server database.

If you want to see the code in details, please check the following repository: https://github.com/Odonno/cqrs-dotnet-core

A command

First, create a list of commands that will be used in your system.

public class OpenParkingCommand
{
    public string ParkingName { get; set; }
}

Now, when you receive the action to open a parking, you set the command and handle it inside your own system, which can looks like this:

public void Handle(OpenParkingCommand command)
{
    var parking = _dbContext.Set<Models.Parking>()
        .FirstOrDefault(p => p.Name == command.ParkingName);

    if (parking == null)
    {
        throw new Exception($"Cannot find parking '{command.ParkingName}'.");
    }
    if (parking.IsOpened)
    {
        throw new Exception($"Parking '{command.ParkingName}' is already opened.");
    }

    parking.IsOpened = true;
    _dbContext.SaveChanges();

    _commandStoreService.Push(command);
}

A query

Same for queries, list all queries that will be used in your system.

public class GetParkingInfoQuery
{
    public string ParkingName { get; set; }
}

And handle those queries inside a query handler:

public ParkingInfo Handle(GetParkingInfoQuery query)
{
    var parking = _dbContext.Set<Models.Parking>()
        .Include(p => p.Places)
        .FirstOrDefault(p => p.Name == query.ParkingName);

    if (parking == null)
    {
        throw new Exception($"Cannot find parking '{query.ParkingName}'.");
    }

    return new ParkingInfo
    {
        Name = parking.Name,
        IsOpened = parking.IsOpened,
        MaximumPlaces = parking.Places.Count,
        AvailablePlaces = 
            parking.IsOpened 
                ? parking.Places.Where(pp => pp.IsFree).Count()
                : 0
    };
}

Beyond CQRS

GraphQL

If you are familiar with GraphQL, you may know that it implements CQRS by design:

  • Query = Read Model
  • Mutation = Write Model

Command Sourcing

Once you have a working CQRS architecture, you can persist every command executed in your application inside a database called a Command Store.

A Command Store is pretty much a logging system where you can retrieve every change made in your system.

Because it is like a logging system, you can design your Command Store as a push only database/collection. And following our example, it can look like this:

public void Push(object command)
{
    _dbContext.Set<Command>().Add(
        new Command
        {
            Type = command.GetType().Name,
            Data = JsonConvert.SerializeObject(command),
            CreatedAt = DateTime.Now,
            UserId = _authenticationService.GetUserId()
        }
    );
    _dbContext.SaveChanges();
}

Event Sourcing

Event Sourcing is a much more complex pattern designed to create a system around events where:

  • Events are the single source of truth (Write Model)
  • Data and services are the result of these events (Read Model)

I will not explain this pattern here but it has a strong relationship with CQRS in a way it separates the events (Write Model) from the queries (Read Model).

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].