SlideShare uma empresa Scribd logo
1 de 39
CQRS and Event Sourcing in
.NET
.NET Excellence Center at Intellias
Sergiy Seletsky
Senior Solutions Architect
MEETUP
.NET Excellence Center – what is it?
 Community development
 Presales support
 Consulting
 Interview support and preparation
 Mentorship
 Employee Assessment
 And more…
Intellias CoEs is a virtual organization of proactive people, who go beyond their regular
duties and employ their expertise where this is crucial for the company to succeed.
Join our team of proactive experts  if you are senior+, of course ;)
For details contact: Tetiana Kulbatska
Agenda
 Pain points of traditional architecture
 CQS and CQRS theory
 Event Sourcing in .NET
 DDD and Event-driven microservices
 Reference implementation for .NET
 Q&A
• Scalability of System is by larger and larger
RDBMS
• Surprise, surprise! 
• Persistence means ‘save the Current State’ of
the domain model
• Query concerns are at odds with Transactional
concerns
• System audit adds extra complexity
• Issues with complex data schema versioning
• more…
Application Design Pain Points
Domain
Modeling Pain
Points Business Rules only exist in user’s
heads
 Converting Domain Objects to DTOs
(and back again!)
 Domain Object Persistence
 Lazy vs. Eager Fetching
 Optimizing Domain for efficient
Queries
 Setter/Getter Anti-Pattern
 Tests are (often) brittle
 more…
Business Pain
Points
 Must know what business questions
we want to ask up front
 Optimizing for Queries and
Optimizing for Transactions are tied
together (and very expensive)
 Evolving Requirements is
hard/expensive
 more…
What is
CQS & CQRS?
Command-Query Separation
• Command-Query Separation (CQS) states that every method
should either be a command that performs an action, or a query
that returns data to the caller, but not both.
• In other words, asking a question should not change the answer.
• More formally, methods should return a value only if they are
referentially transparent and hence possess no side effects.
Query - returns data and not apply any changes
Command - apply changes and not returns data, only result of
execution
CQS in Action
From CRUD to CQS
Interface Segregation Principle
Command-Query
Responsibility Segregation
• The CQS principles applied to your
domain modeling and system architecture
• Enable each element of your architecture
to be optimized for a single responsibility
• Decomposition for your architecture rather
than just for your objects
LAN/WAN
Application Services
Domain
Object
Domain
Object
Domain
Object
Domain
Object
Client
Remote Services
Request
DTO
ReturnDTO
Command
ACK
Returned
RDBMS
Traditional Architecture
LAN/WAN
Slicing and Dicing our Architecture
Application Services
Domain
Object
Domain
Object
Domain
Object
Domain
Object
Client
Remote Services
Request
DTO
ReturnDTO
Command
ACK
Returned
RDBMS
Client
Server
WriteRead
LAN/WAN
Refactoring our Architecture
Application Services
Domain
Object
Domain
Object
Client
Remote Services
Request
DTO
ReturnDTO
Application Services
Command
ACK
Returned
WriteRead
Light-Weight Query
Services
RDBMS
Domain
Object
Domain
Object
Persistence Persistence
Remote ServicesRemote Services
Eventually
Command Query Responsibility Segregation
Read StorageEvents Storage
APIs
Write
Model
Read
ModelEvents
Command
Query
Write Model
Write
Model
Events
Command
Handler
Event
Handler
EventBus/EventStore
Domain
Model
Repository
REST commandBus.Send( CreateJobProfile(jobProfile) );
[CommandHandler]
public Task Handle(CreateJobProfileCommand
command) {
//check if exist
repository.FindEntity();
event = new JobProfileCreated(command.entity);
RaiseEvent(event);
[EventHandler]
public void HandleCreated(JobProfileCreated event) {
entity = new JobProfileQueryModel( event.Entity );
repository.Save( entity );
}
CmdBu
s
Read Model
Write
Model
EventBus/EventStore Event
Handler
Domain
Model
Events
Repository
REST
[EventHandler]
public void Handle(JobProfileCreated event) {
entity = new CareerMatrixQueryModel( event.Entity );
//extra projections happened here
repository.Save(entity);
As many read models as you want
With No performance degradation
UI
Write
Model
Events
Command
Query
Read
ModelRead
ModelRead
Model
C PA
CAP Theorem:
onsistency, vailability, artition-Tolerance; pick any two!
Write
Read
Scaling of Distributed Systems
C A P
Event Sourcing
in .NET
Event Sourcing pattern
Event Sourcing advantages
 Events are immutable and can be stored using an append-only
operation.
 Events are simple objects that describe some action that occurred
 Events typically have meaning for a domain expert
 Event sourcing can help prevent concurrent updates from causing
conflicts because it avoids the requirement to directly update objects in
the data store
 The append-only storage of events provides an audit trail that can be
used to monitor actions taken against a data store
 The event store raises events, and tasks perform operations in
response to those events.
ASP.NET Core – APIs Controller
public class InventoryController: Controller {
private readonly ICommandBus commandBus;
private readonly IReadModelFacade queryModel;
public InventoryController(ICommandBus bus, IReadModelFacade facade) {
queryModel = facade;
commandBus = bus;
}
[HttpGet]
public async Task<IActionResult<IQuerable<InventoryQueryItem>>> Query() {
return await queryModel.GetInventoryItemsQueryAsync();
}
[HttpGet("{id}")]
public async Task<IActionResult<InventoryQueryItem>> QueryById(string id) {
return await queryModel.GetInventoryItemAsync(id);
}
[HttpPost]
public async Task<IActionResult<IExecutionResult>> Add(CreateInventoryItem command) {
return await commandBus.SendAsync(command);
}
[HttpPut("/change-name")]
public async Task<IActionResult<IExecutionResult>> ChangeName(RenameInventoryItem command) {
return await commandBus.SendAsync(command);
}
[HttpPut("/check-in")]
public async Task<IActionResult<IExecutionResult>> CheckIn(CheckInItemsToInventory command) {
return await commandBus.SendAsync(command);
}
[HttpPut("/remove")]
public async Task<IActionResult<IExecutionResult>> Remove(RemoveItemsFromInventory command) {
return await commandBus.SendAsync(command);
}
[HttpDelete]
public async Task<IActionResult<IExecutionResult>> Deactivate(DeactivateInventoryItem command) {
return await commandBus.SendAsync(command);
}
}
NoCRUD–generalupdatenotallowed
Allupdatesseparatedbycommands
ExecutionresultmayreturncorrelationID
APIs Gateway
ASP.NET Core – Command Handler
public class InventoryCommandHandlers : ICommandHandler<CreateInventoryItem>,
ICommandHandler<DeactivateInventoryItem>,
ICommandHandler<RemoveItemsFromInventory>,
ICommandHandler<CheckInItemsToInventory>,
ICommandHandler<RenameInventoryItem>
{
private readonly ISession _session;
public InventoryCommandHandlers(ISession session)
{
_session = session;
}
public async Task Handle(CreateInventoryItem command)
{
var item = new InventoryItem(command.Id, command.Name);
await _session.Add(item);
await _session.Commit();
}
public async Task Handle(DeactivateInventoryItem command)
{
var item = await _session.Get<InventoryItem>(command.Id, command.ExpectedVersion);
item.Deactivate();
await _session.Commit();
}
public async Task Handle(RemoveItemsFromInventory command)
{
var item = await _session.Get<InventoryItem>(command.Id, command.ExpectedVersion);
item.Remove(command.Count);
await _session.Commit();
}
public async Task Handle(CheckInItemsToInventory command)
{
var item = await _session.Get<InventoryItem>(command.Id, command.ExpectedVersion);
item.CheckIn(command.Count);
await _session.Commit();
}
public async Task Handle(RenameInventoryItem command)
{
var item = await _session.Get<InventoryItem>(command.Id, command.ExpectedVersion);
item.ChangeName(command.NewName);
Execution of commands on domain object
ASP.NET Core – Event Handler
public class InventoryListView : IEventHandler<InventoryItemCreated>,
IEventHandler<InventoryItemRenamed>,
IEventHandler<InventoryItemDeactivated>
{
public Task Handle(InventoryItemCreated message)
{
InMemoryDatabase.List.Add(new InventoryItemListDto(message.Id, message.Name));
return Task.CompletedTask;
}
public Task Handle(InventoryItemRenamed message)
{
var item = InMemoryDatabase.List.Find(x => x.Id == message.Id);
item.Name = message.NewName;
return Task.CompletedTask;
}
public Task Handle(InventoryItemDeactivated message)
{
InMemoryDatabase.List.RemoveAll(x => x.Id == message.Id);
return Task.CompletedTask;
}
}
Building denormalized/materialized query views
ASP.NET Core – Aggregate Rootpublic class InventoryItem : AggregateRoot
{
private bool _activated;
private InventoryItem(){}
public InventoryItem(string id, string name)
{
Id = id;
ApplyChange(new InventoryItemCreated(id, name));
}
private void Apply(InventoryItemCreated e)
{
_activated = true;
}
private void Apply(InventoryItemDeactivated e)
{
_activated = false;
}
public void ChangeName(string newName)
{
if (string.IsNullOrEmpty(newName)) throw new ArgumentException("newName");
ApplyChange(new InventoryItemRenamed(Id, newName));
}
public void Remove(int count)
{
if (count <= 0) throw new InvalidOperationException("cant remove negative count from inventory");
ApplyChange(new ItemsRemovedFromInventory(Id, count));
}
public void CheckIn(int count)
{
if(count <= 0) throw new InvalidOperationException("must have a count greater than 0 to add to inventory");
ApplyChange(new ItemsCheckedInToInventory(Id, count));
}
public void Deactivate()
{
if(!_activated) throw new InvalidOperationException("already deactivated");
ApplyChange(new InventoryItemDeactivated(Id));
}
}
Clean & centralized domain-driven business logic
Event-driven
microservices
Domain boundaries is a key to
success
Define cross-boundary domain events
Event storming
The Art of Scalability
CQRS & ES
Infinite Scale
Unlimited scalability
Power of Azure via Event Grid
Production ready event sourcing platform
Event is a single source of truth
No data losing and easy recovery and audit
.NET Reference implementations
EventFlow
https://github.com/eventflow/EventFlow
https://github.com/gautema/CQRSlite
https://github.com/OpenCQRS/OpenCQRS
https://dev.azure.com/IntelliasTS/IntelliGrowth
MediatR
https://github.com/jbogard/MediatR
IntelliGrowth - Inner Sourcing Initiative
IntelliGrowth – Serverless Cloud
Architecture
Questions<An
y>?
dotnet@Intellias.com
Reading
Domain Driven Design
Eric Evans
Building Microservices
Sam Newman
Exploring CQRS and Event Sourcing
Dominic Betts
Resources
 Greg Young - Building an Event Storage
 Microsoft - Exploring CQRS and Event Sourcing
 Greg Young - CQRS & Event Sourcing
 Lorenzo Nicora - A visual introduction to event sourcing and cqrs
 Greg Young - A Decade of DDD, CQRS, Event Sourcing
 Martin Fowler - Event Sourcing
 Eric Evans - DDD and Microservices: At Last, Some Boudaries!
 Martin Kleppmann — Event Sourcing and Stream Processing at Scale
 Julie Lerman - Data Points - CQRS and EF Data Models
 Vaughn Vernon - Reactive DDD: Modeling Uncertainty
 Mark Seemann - CQS versus server generated IDs
 Udi Dahan - If (domain logic) then CQRS, or Saga?
 Event Store - The open-source, functional database with Complex Event Processing in JavaScript
 Pedro Costa - Migrating to Microservices and Event-Sourcing: the Dos and Dont’s
 David Boike - Putting your events on a diet
 DDD Quickly
 Dennis Doomen - The Good, The Bad and the Ugly of Event Sourcing
 Liquid Projections - A set of highly efficient building blocks to build fast autonomous synchronous and asynchronous projector

Mais conteúdo relacionado

Mais procurados

Real-Time Data Flows with Apache NiFi
Real-Time Data Flows with Apache NiFiReal-Time Data Flows with Apache NiFi
Real-Time Data Flows with Apache NiFiManish Gupta
 
Big Data Redis Mongodb Dynamodb Sharding
Big Data Redis Mongodb Dynamodb ShardingBig Data Redis Mongodb Dynamodb Sharding
Big Data Redis Mongodb Dynamodb ShardingAraf Karsh Hamid
 
Agile, User Stories, Domain Driven Design
Agile, User Stories, Domain Driven DesignAgile, User Stories, Domain Driven Design
Agile, User Stories, Domain Driven DesignAraf Karsh Hamid
 
ASP.NET Developer Roadmap 2021
ASP.NET Developer Roadmap 2021ASP.NET Developer Roadmap 2021
ASP.NET Developer Roadmap 2021Ronak Sankhala
 
Streaming Data Lakes using Kafka Connect + Apache Hudi | Vinoth Chandar, Apac...
Streaming Data Lakes using Kafka Connect + Apache Hudi | Vinoth Chandar, Apac...Streaming Data Lakes using Kafka Connect + Apache Hudi | Vinoth Chandar, Apac...
Streaming Data Lakes using Kafka Connect + Apache Hudi | Vinoth Chandar, Apac...HostedbyConfluent
 
Introduction to Apache Kafka
Introduction to Apache KafkaIntroduction to Apache Kafka
Introduction to Apache KafkaShiao-An Yuan
 
Java Application Modernization Patterns and Stories from the IBM Garage
Java Application Modernization Patterns and Stories from the IBM GarageJava Application Modernization Patterns and Stories from the IBM Garage
Java Application Modernization Patterns and Stories from the IBM GarageHolly Cummins
 
Schema Registry 101 with Bill Bejeck | Kafka Summit London 2022
Schema Registry 101 with Bill Bejeck | Kafka Summit London 2022Schema Registry 101 with Bill Bejeck | Kafka Summit London 2022
Schema Registry 101 with Bill Bejeck | Kafka Summit London 2022HostedbyConfluent
 
CI/CD Overview
CI/CD OverviewCI/CD Overview
CI/CD OverviewAn Nguyen
 
Building Event Driven (Micro)services with Apache Kafka
Building Event Driven (Micro)services with Apache KafkaBuilding Event Driven (Micro)services with Apache Kafka
Building Event Driven (Micro)services with Apache KafkaGuido Schmutz
 
Domain-Driven Design
Domain-Driven DesignDomain-Driven Design
Domain-Driven DesignAndriy Buday
 
Event Sourcing & CQRS, Kafka, Rabbit MQ
Event Sourcing & CQRS, Kafka, Rabbit MQEvent Sourcing & CQRS, Kafka, Rabbit MQ
Event Sourcing & CQRS, Kafka, Rabbit MQAraf Karsh Hamid
 
Introducing Domain Driven Design - codemash
Introducing Domain Driven Design - codemashIntroducing Domain Driven Design - codemash
Introducing Domain Driven Design - codemashSteven Smith
 
Introduction to microservices
Introduction to microservicesIntroduction to microservices
Introduction to microservicesAnil Allewar
 
Azure DataBricks for Data Engineering by Eugene Polonichko
Azure DataBricks for Data Engineering by Eugene PolonichkoAzure DataBricks for Data Engineering by Eugene Polonichko
Azure DataBricks for Data Engineering by Eugene PolonichkoDimko Zhluktenko
 

Mais procurados (20)

Real-Time Data Flows with Apache NiFi
Real-Time Data Flows with Apache NiFiReal-Time Data Flows with Apache NiFi
Real-Time Data Flows with Apache NiFi
 
Big Data Redis Mongodb Dynamodb Sharding
Big Data Redis Mongodb Dynamodb ShardingBig Data Redis Mongodb Dynamodb Sharding
Big Data Redis Mongodb Dynamodb Sharding
 
infrastructure as code
infrastructure as codeinfrastructure as code
infrastructure as code
 
Agile, User Stories, Domain Driven Design
Agile, User Stories, Domain Driven DesignAgile, User Stories, Domain Driven Design
Agile, User Stories, Domain Driven Design
 
ASP.NET Developer Roadmap 2021
ASP.NET Developer Roadmap 2021ASP.NET Developer Roadmap 2021
ASP.NET Developer Roadmap 2021
 
(ARC307) Infrastructure as Code
(ARC307) Infrastructure as Code(ARC307) Infrastructure as Code
(ARC307) Infrastructure as Code
 
Domain Driven Design
Domain Driven DesignDomain Driven Design
Domain Driven Design
 
Streaming Data Lakes using Kafka Connect + Apache Hudi | Vinoth Chandar, Apac...
Streaming Data Lakes using Kafka Connect + Apache Hudi | Vinoth Chandar, Apac...Streaming Data Lakes using Kafka Connect + Apache Hudi | Vinoth Chandar, Apac...
Streaming Data Lakes using Kafka Connect + Apache Hudi | Vinoth Chandar, Apac...
 
Introduction to Apache Kafka
Introduction to Apache KafkaIntroduction to Apache Kafka
Introduction to Apache Kafka
 
Java Application Modernization Patterns and Stories from the IBM Garage
Java Application Modernization Patterns and Stories from the IBM GarageJava Application Modernization Patterns and Stories from the IBM Garage
Java Application Modernization Patterns and Stories from the IBM Garage
 
Kafka 101
Kafka 101Kafka 101
Kafka 101
 
Schema Registry 101 with Bill Bejeck | Kafka Summit London 2022
Schema Registry 101 with Bill Bejeck | Kafka Summit London 2022Schema Registry 101 with Bill Bejeck | Kafka Summit London 2022
Schema Registry 101 with Bill Bejeck | Kafka Summit London 2022
 
CI/CD Overview
CI/CD OverviewCI/CD Overview
CI/CD Overview
 
Building Event Driven (Micro)services with Apache Kafka
Building Event Driven (Micro)services with Apache KafkaBuilding Event Driven (Micro)services with Apache Kafka
Building Event Driven (Micro)services with Apache Kafka
 
Domain-Driven Design
Domain-Driven DesignDomain-Driven Design
Domain-Driven Design
 
Event Sourcing & CQRS, Kafka, Rabbit MQ
Event Sourcing & CQRS, Kafka, Rabbit MQEvent Sourcing & CQRS, Kafka, Rabbit MQ
Event Sourcing & CQRS, Kafka, Rabbit MQ
 
Introducing Domain Driven Design - codemash
Introducing Domain Driven Design - codemashIntroducing Domain Driven Design - codemash
Introducing Domain Driven Design - codemash
 
Integrating Apache Spark and NiFi for Data Lakes
Integrating Apache Spark and NiFi for Data LakesIntegrating Apache Spark and NiFi for Data Lakes
Integrating Apache Spark and NiFi for Data Lakes
 
Introduction to microservices
Introduction to microservicesIntroduction to microservices
Introduction to microservices
 
Azure DataBricks for Data Engineering by Eugene Polonichko
Azure DataBricks for Data Engineering by Eugene PolonichkoAzure DataBricks for Data Engineering by Eugene Polonichko
Azure DataBricks for Data Engineering by Eugene Polonichko
 

Semelhante a CQRS and Event Sourcing

Cqrs and event sourcing in azure
Cqrs and event sourcing in azureCqrs and event sourcing in azure
Cqrs and event sourcing in azureSergey Seletsky
 
DDD, CQRS and testing with ASP.Net MVC
DDD, CQRS and testing with ASP.Net MVCDDD, CQRS and testing with ASP.Net MVC
DDD, CQRS and testing with ASP.Net MVCAndy Butland
 
[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade Serverless[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade ServerlessKatyShimizu
 
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade ServerlessKatyShimizu
 
El camino a las Cloud Native Apps - Introduction
El camino a las Cloud Native Apps - IntroductionEl camino a las Cloud Native Apps - Introduction
El camino a las Cloud Native Apps - IntroductionPlain Concepts
 
Decomposing the Monolith using modern-day .NET and a touch of microservices
Decomposing the Monolith using modern-day .NET and a touch of microservicesDecomposing the Monolith using modern-day .NET and a touch of microservices
Decomposing the Monolith using modern-day .NET and a touch of microservicesDennis Doomen
 
Working with data using Azure Functions.pdf
Working with data using Azure Functions.pdfWorking with data using Azure Functions.pdf
Working with data using Azure Functions.pdfStephanie Locke
 
Building workflow solution with Microsoft Azure and Cloud | Integration Monday
Building workflow solution with Microsoft Azure and Cloud | Integration MondayBuilding workflow solution with Microsoft Azure and Cloud | Integration Monday
Building workflow solution with Microsoft Azure and Cloud | Integration MondayBizTalk360
 
Integration-Monday-Stateful-Programming-Models-Serverless-Functions
Integration-Monday-Stateful-Programming-Models-Serverless-FunctionsIntegration-Monday-Stateful-Programming-Models-Serverless-Functions
Integration-Monday-Stateful-Programming-Models-Serverless-FunctionsBizTalk360
 
Develop in ludicrous mode with azure serverless
Develop in ludicrous mode with azure serverlessDevelop in ludicrous mode with azure serverless
Develop in ludicrous mode with azure serverlessLalit Kale
 
Containerisation Hack of a Legacy Software Solution - Alex Carter - CodeMill ...
Containerisation Hack of a Legacy Software Solution - Alex Carter - CodeMill ...Containerisation Hack of a Legacy Software Solution - Alex Carter - CodeMill ...
Containerisation Hack of a Legacy Software Solution - Alex Carter - CodeMill ...CodeMill digital skills
 
Command Query Responsibility Segregation and Event Sourcing
Command Query Responsibility Segregation and Event SourcingCommand Query Responsibility Segregation and Event Sourcing
Command Query Responsibility Segregation and Event SourcingMitinPavel
 
An Introduction To CQRS
An Introduction To CQRSAn Introduction To CQRS
An Introduction To CQRSNeil Robbins
 
Greenfield Development with CQRS
Greenfield Development with CQRSGreenfield Development with CQRS
Greenfield Development with CQRSDavid Hoerster
 
MongoDB World 2018: Ch-Ch-Ch-Ch-Changes: Taking Your Stitch Application to th...
MongoDB World 2018: Ch-Ch-Ch-Ch-Changes: Taking Your Stitch Application to th...MongoDB World 2018: Ch-Ch-Ch-Ch-Changes: Taking Your Stitch Application to th...
MongoDB World 2018: Ch-Ch-Ch-Ch-Changes: Taking Your Stitch Application to th...MongoDB
 
Developing Next-Gen Enterprise Web Application
Developing Next-Gen Enterprise Web ApplicationDeveloping Next-Gen Enterprise Web Application
Developing Next-Gen Enterprise Web ApplicationMark Gu
 
Optimizing Code Reusability for SharePoint using Linq to SharePoint & the MVP...
Optimizing Code Reusability for SharePoint using Linq to SharePoint & the MVP...Optimizing Code Reusability for SharePoint using Linq to SharePoint & the MVP...
Optimizing Code Reusability for SharePoint using Linq to SharePoint & the MVP...Sparkhound Inc.
 
Building stateful serverless orchestrations with Azure Durable Azure Function...
Building stateful serverless orchestrations with Azure Durable Azure Function...Building stateful serverless orchestrations with Azure Durable Azure Function...
Building stateful serverless orchestrations with Azure Durable Azure Function...Callon Campbell
 

Semelhante a CQRS and Event Sourcing (20)

Cqrs and event sourcing in azure
Cqrs and event sourcing in azureCqrs and event sourcing in azure
Cqrs and event sourcing in azure
 
DDD, CQRS and testing with ASP.Net MVC
DDD, CQRS and testing with ASP.Net MVCDDD, CQRS and testing with ASP.Net MVC
DDD, CQRS and testing with ASP.Net MVC
 
Tdd,Ioc
Tdd,IocTdd,Ioc
Tdd,Ioc
 
[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade Serverless[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade Serverless
 
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
 
El camino a las Cloud Native Apps - Introduction
El camino a las Cloud Native Apps - IntroductionEl camino a las Cloud Native Apps - Introduction
El camino a las Cloud Native Apps - Introduction
 
Decomposing the Monolith using modern-day .NET and a touch of microservices
Decomposing the Monolith using modern-day .NET and a touch of microservicesDecomposing the Monolith using modern-day .NET and a touch of microservices
Decomposing the Monolith using modern-day .NET and a touch of microservices
 
Clean Architecture @ Taxibeat
Clean Architecture @ TaxibeatClean Architecture @ Taxibeat
Clean Architecture @ Taxibeat
 
Working with data using Azure Functions.pdf
Working with data using Azure Functions.pdfWorking with data using Azure Functions.pdf
Working with data using Azure Functions.pdf
 
Building workflow solution with Microsoft Azure and Cloud | Integration Monday
Building workflow solution with Microsoft Azure and Cloud | Integration MondayBuilding workflow solution with Microsoft Azure and Cloud | Integration Monday
Building workflow solution with Microsoft Azure and Cloud | Integration Monday
 
Integration-Monday-Stateful-Programming-Models-Serverless-Functions
Integration-Monday-Stateful-Programming-Models-Serverless-FunctionsIntegration-Monday-Stateful-Programming-Models-Serverless-Functions
Integration-Monday-Stateful-Programming-Models-Serverless-Functions
 
Develop in ludicrous mode with azure serverless
Develop in ludicrous mode with azure serverlessDevelop in ludicrous mode with azure serverless
Develop in ludicrous mode with azure serverless
 
Containerisation Hack of a Legacy Software Solution - Alex Carter - CodeMill ...
Containerisation Hack of a Legacy Software Solution - Alex Carter - CodeMill ...Containerisation Hack of a Legacy Software Solution - Alex Carter - CodeMill ...
Containerisation Hack of a Legacy Software Solution - Alex Carter - CodeMill ...
 
Command Query Responsibility Segregation and Event Sourcing
Command Query Responsibility Segregation and Event SourcingCommand Query Responsibility Segregation and Event Sourcing
Command Query Responsibility Segregation and Event Sourcing
 
An Introduction To CQRS
An Introduction To CQRSAn Introduction To CQRS
An Introduction To CQRS
 
Greenfield Development with CQRS
Greenfield Development with CQRSGreenfield Development with CQRS
Greenfield Development with CQRS
 
MongoDB World 2018: Ch-Ch-Ch-Ch-Changes: Taking Your Stitch Application to th...
MongoDB World 2018: Ch-Ch-Ch-Ch-Changes: Taking Your Stitch Application to th...MongoDB World 2018: Ch-Ch-Ch-Ch-Changes: Taking Your Stitch Application to th...
MongoDB World 2018: Ch-Ch-Ch-Ch-Changes: Taking Your Stitch Application to th...
 
Developing Next-Gen Enterprise Web Application
Developing Next-Gen Enterprise Web ApplicationDeveloping Next-Gen Enterprise Web Application
Developing Next-Gen Enterprise Web Application
 
Optimizing Code Reusability for SharePoint using Linq to SharePoint & the MVP...
Optimizing Code Reusability for SharePoint using Linq to SharePoint & the MVP...Optimizing Code Reusability for SharePoint using Linq to SharePoint & the MVP...
Optimizing Code Reusability for SharePoint using Linq to SharePoint & the MVP...
 
Building stateful serverless orchestrations with Azure Durable Azure Function...
Building stateful serverless orchestrations with Azure Durable Azure Function...Building stateful serverless orchestrations with Azure Durable Azure Function...
Building stateful serverless orchestrations with Azure Durable Azure Function...
 

Mais de Sergey Seletsky

Intellias CQRS Framework
Intellias CQRS FrameworkIntellias CQRS Framework
Intellias CQRS FrameworkSergey Seletsky
 
Go Serverless with Azure
Go Serverless with AzureGo Serverless with Azure
Go Serverless with AzureSergey Seletsky
 
Microservice.net by sergey seletsky
Microservice.net by sergey seletskyMicroservice.net by sergey seletsky
Microservice.net by sergey seletskySergey Seletsky
 
Continuous delivery by sergey seletsky
Continuous delivery by sergey seletskyContinuous delivery by sergey seletsky
Continuous delivery by sergey seletskySergey Seletsky
 
Asp.net mvc 5 course module 1 overview
Asp.net mvc 5 course   module 1 overviewAsp.net mvc 5 course   module 1 overview
Asp.net mvc 5 course module 1 overviewSergey Seletsky
 
Mobile development with visual studio
Mobile development with visual studioMobile development with visual studio
Mobile development with visual studioSergey Seletsky
 
Make your project up to date
Make your project up to dateMake your project up to date
Make your project up to dateSergey Seletsky
 

Mais de Sergey Seletsky (13)

CICD Azure DevOps
CICD Azure DevOpsCICD Azure DevOps
CICD Azure DevOps
 
Intellias CQRS Framework
Intellias CQRS FrameworkIntellias CQRS Framework
Intellias CQRS Framework
 
Go Serverless with Azure
Go Serverless with AzureGo Serverless with Azure
Go Serverless with Azure
 
IoT Smart Home
IoT Smart HomeIoT Smart Home
IoT Smart Home
 
WiFi anywhere
WiFi anywhereWiFi anywhere
WiFi anywhere
 
MicroServices on Azure
MicroServices on AzureMicroServices on Azure
MicroServices on Azure
 
Microservice.net by sergey seletsky
Microservice.net by sergey seletskyMicroservice.net by sergey seletsky
Microservice.net by sergey seletsky
 
Continuous delivery by sergey seletsky
Continuous delivery by sergey seletskyContinuous delivery by sergey seletsky
Continuous delivery by sergey seletsky
 
Asp.net mvc 5 course module 1 overview
Asp.net mvc 5 course   module 1 overviewAsp.net mvc 5 course   module 1 overview
Asp.net mvc 5 course module 1 overview
 
Mobile development with visual studio
Mobile development with visual studioMobile development with visual studio
Mobile development with visual studio
 
Make your project up to date
Make your project up to dateMake your project up to date
Make your project up to date
 
Scrum and Kanban
Scrum and KanbanScrum and Kanban
Scrum and Kanban
 
Eco system apps
Eco system appsEco system apps
Eco system apps
 

Último

WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareJim McKeeth
 
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...Jittipong Loespradit
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...masabamasaba
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisamasabamasaba
 
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...Shane Coughlan
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisamasabamasaba
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park masabamasaba
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfonteinmasabamasaba
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfonteinmasabamasaba
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Bert Jan Schrijver
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastPapp Krisztián
 
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2
 
WSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburgmasabamasaba
 

Último (20)

WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go Platformless
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
WSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security Program
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
 

CQRS and Event Sourcing

  • 1. CQRS and Event Sourcing in .NET .NET Excellence Center at Intellias Sergiy Seletsky Senior Solutions Architect MEETUP
  • 2. .NET Excellence Center – what is it?  Community development  Presales support  Consulting  Interview support and preparation  Mentorship  Employee Assessment  And more… Intellias CoEs is a virtual organization of proactive people, who go beyond their regular duties and employ their expertise where this is crucial for the company to succeed. Join our team of proactive experts  if you are senior+, of course ;) For details contact: Tetiana Kulbatska
  • 3. Agenda  Pain points of traditional architecture  CQS and CQRS theory  Event Sourcing in .NET  DDD and Event-driven microservices  Reference implementation for .NET  Q&A
  • 4. • Scalability of System is by larger and larger RDBMS • Surprise, surprise!  • Persistence means ‘save the Current State’ of the domain model • Query concerns are at odds with Transactional concerns • System audit adds extra complexity • Issues with complex data schema versioning • more… Application Design Pain Points
  • 5. Domain Modeling Pain Points Business Rules only exist in user’s heads  Converting Domain Objects to DTOs (and back again!)  Domain Object Persistence  Lazy vs. Eager Fetching  Optimizing Domain for efficient Queries  Setter/Getter Anti-Pattern  Tests are (often) brittle  more…
  • 6. Business Pain Points  Must know what business questions we want to ask up front  Optimizing for Queries and Optimizing for Transactions are tied together (and very expensive)  Evolving Requirements is hard/expensive  more…
  • 8. Command-Query Separation • Command-Query Separation (CQS) states that every method should either be a command that performs an action, or a query that returns data to the caller, but not both. • In other words, asking a question should not change the answer. • More formally, methods should return a value only if they are referentially transparent and hence possess no side effects. Query - returns data and not apply any changes Command - apply changes and not returns data, only result of execution
  • 12. Command-Query Responsibility Segregation • The CQS principles applied to your domain modeling and system architecture • Enable each element of your architecture to be optimized for a single responsibility • Decomposition for your architecture rather than just for your objects
  • 14. LAN/WAN Slicing and Dicing our Architecture Application Services Domain Object Domain Object Domain Object Domain Object Client Remote Services Request DTO ReturnDTO Command ACK Returned RDBMS Client Server WriteRead
  • 15. LAN/WAN Refactoring our Architecture Application Services Domain Object Domain Object Client Remote Services Request DTO ReturnDTO Application Services Command ACK Returned WriteRead Light-Weight Query Services RDBMS Domain Object Domain Object Persistence Persistence Remote ServicesRemote Services Eventually
  • 16. Command Query Responsibility Segregation Read StorageEvents Storage APIs Write Model Read ModelEvents Command Query
  • 17. Write Model Write Model Events Command Handler Event Handler EventBus/EventStore Domain Model Repository REST commandBus.Send( CreateJobProfile(jobProfile) ); [CommandHandler] public Task Handle(CreateJobProfileCommand command) { //check if exist repository.FindEntity(); event = new JobProfileCreated(command.entity); RaiseEvent(event); [EventHandler] public void HandleCreated(JobProfileCreated event) { entity = new JobProfileQueryModel( event.Entity ); repository.Save( entity ); } CmdBu s
  • 18. Read Model Write Model EventBus/EventStore Event Handler Domain Model Events Repository REST [EventHandler] public void Handle(JobProfileCreated event) { entity = new CareerMatrixQueryModel( event.Entity ); //extra projections happened here repository.Save(entity);
  • 19. As many read models as you want With No performance degradation UI Write Model Events Command Query Read ModelRead ModelRead Model
  • 20. C PA CAP Theorem: onsistency, vailability, artition-Tolerance; pick any two! Write Read Scaling of Distributed Systems C A P
  • 23. Event Sourcing advantages  Events are immutable and can be stored using an append-only operation.  Events are simple objects that describe some action that occurred  Events typically have meaning for a domain expert  Event sourcing can help prevent concurrent updates from causing conflicts because it avoids the requirement to directly update objects in the data store  The append-only storage of events provides an audit trail that can be used to monitor actions taken against a data store  The event store raises events, and tasks perform operations in response to those events.
  • 24. ASP.NET Core – APIs Controller public class InventoryController: Controller { private readonly ICommandBus commandBus; private readonly IReadModelFacade queryModel; public InventoryController(ICommandBus bus, IReadModelFacade facade) { queryModel = facade; commandBus = bus; } [HttpGet] public async Task<IActionResult<IQuerable<InventoryQueryItem>>> Query() { return await queryModel.GetInventoryItemsQueryAsync(); } [HttpGet("{id}")] public async Task<IActionResult<InventoryQueryItem>> QueryById(string id) { return await queryModel.GetInventoryItemAsync(id); } [HttpPost] public async Task<IActionResult<IExecutionResult>> Add(CreateInventoryItem command) { return await commandBus.SendAsync(command); } [HttpPut("/change-name")] public async Task<IActionResult<IExecutionResult>> ChangeName(RenameInventoryItem command) { return await commandBus.SendAsync(command); } [HttpPut("/check-in")] public async Task<IActionResult<IExecutionResult>> CheckIn(CheckInItemsToInventory command) { return await commandBus.SendAsync(command); } [HttpPut("/remove")] public async Task<IActionResult<IExecutionResult>> Remove(RemoveItemsFromInventory command) { return await commandBus.SendAsync(command); } [HttpDelete] public async Task<IActionResult<IExecutionResult>> Deactivate(DeactivateInventoryItem command) { return await commandBus.SendAsync(command); } } NoCRUD–generalupdatenotallowed Allupdatesseparatedbycommands ExecutionresultmayreturncorrelationID APIs Gateway
  • 25. ASP.NET Core – Command Handler public class InventoryCommandHandlers : ICommandHandler<CreateInventoryItem>, ICommandHandler<DeactivateInventoryItem>, ICommandHandler<RemoveItemsFromInventory>, ICommandHandler<CheckInItemsToInventory>, ICommandHandler<RenameInventoryItem> { private readonly ISession _session; public InventoryCommandHandlers(ISession session) { _session = session; } public async Task Handle(CreateInventoryItem command) { var item = new InventoryItem(command.Id, command.Name); await _session.Add(item); await _session.Commit(); } public async Task Handle(DeactivateInventoryItem command) { var item = await _session.Get<InventoryItem>(command.Id, command.ExpectedVersion); item.Deactivate(); await _session.Commit(); } public async Task Handle(RemoveItemsFromInventory command) { var item = await _session.Get<InventoryItem>(command.Id, command.ExpectedVersion); item.Remove(command.Count); await _session.Commit(); } public async Task Handle(CheckInItemsToInventory command) { var item = await _session.Get<InventoryItem>(command.Id, command.ExpectedVersion); item.CheckIn(command.Count); await _session.Commit(); } public async Task Handle(RenameInventoryItem command) { var item = await _session.Get<InventoryItem>(command.Id, command.ExpectedVersion); item.ChangeName(command.NewName); Execution of commands on domain object
  • 26. ASP.NET Core – Event Handler public class InventoryListView : IEventHandler<InventoryItemCreated>, IEventHandler<InventoryItemRenamed>, IEventHandler<InventoryItemDeactivated> { public Task Handle(InventoryItemCreated message) { InMemoryDatabase.List.Add(new InventoryItemListDto(message.Id, message.Name)); return Task.CompletedTask; } public Task Handle(InventoryItemRenamed message) { var item = InMemoryDatabase.List.Find(x => x.Id == message.Id); item.Name = message.NewName; return Task.CompletedTask; } public Task Handle(InventoryItemDeactivated message) { InMemoryDatabase.List.RemoveAll(x => x.Id == message.Id); return Task.CompletedTask; } } Building denormalized/materialized query views
  • 27. ASP.NET Core – Aggregate Rootpublic class InventoryItem : AggregateRoot { private bool _activated; private InventoryItem(){} public InventoryItem(string id, string name) { Id = id; ApplyChange(new InventoryItemCreated(id, name)); } private void Apply(InventoryItemCreated e) { _activated = true; } private void Apply(InventoryItemDeactivated e) { _activated = false; } public void ChangeName(string newName) { if (string.IsNullOrEmpty(newName)) throw new ArgumentException("newName"); ApplyChange(new InventoryItemRenamed(Id, newName)); } public void Remove(int count) { if (count <= 0) throw new InvalidOperationException("cant remove negative count from inventory"); ApplyChange(new ItemsRemovedFromInventory(Id, count)); } public void CheckIn(int count) { if(count <= 0) throw new InvalidOperationException("must have a count greater than 0 to add to inventory"); ApplyChange(new ItemsCheckedInToInventory(Id, count)); } public void Deactivate() { if(!_activated) throw new InvalidOperationException("already deactivated"); ApplyChange(new InventoryItemDeactivated(Id)); } } Clean & centralized domain-driven business logic
  • 29. Domain boundaries is a key to success
  • 30. Define cross-boundary domain events Event storming
  • 31. The Art of Scalability CQRS & ES Infinite Scale Unlimited scalability
  • 32. Power of Azure via Event Grid Production ready event sourcing platform
  • 33. Event is a single source of truth No data losing and easy recovery and audit
  • 35. IntelliGrowth - Inner Sourcing Initiative
  • 36. IntelliGrowth – Serverless Cloud Architecture
  • 38. Reading Domain Driven Design Eric Evans Building Microservices Sam Newman Exploring CQRS and Event Sourcing Dominic Betts
  • 39. Resources  Greg Young - Building an Event Storage  Microsoft - Exploring CQRS and Event Sourcing  Greg Young - CQRS & Event Sourcing  Lorenzo Nicora - A visual introduction to event sourcing and cqrs  Greg Young - A Decade of DDD, CQRS, Event Sourcing  Martin Fowler - Event Sourcing  Eric Evans - DDD and Microservices: At Last, Some Boudaries!  Martin Kleppmann — Event Sourcing and Stream Processing at Scale  Julie Lerman - Data Points - CQRS and EF Data Models  Vaughn Vernon - Reactive DDD: Modeling Uncertainty  Mark Seemann - CQS versus server generated IDs  Udi Dahan - If (domain logic) then CQRS, or Saga?  Event Store - The open-source, functional database with Complex Event Processing in JavaScript  Pedro Costa - Migrating to Microservices and Event-Sourcing: the Dos and Dont’s  David Boike - Putting your events on a diet  DDD Quickly  Dennis Doomen - The Good, The Bad and the Ugly of Event Sourcing  Liquid Projections - A set of highly efficient building blocks to build fast autonomous synchronous and asynchronous projector