Thursday, December 1, 2016

Comparing DDD + ES + CQRS with DDD without ES, CQRS

When using DDD with ES, CQRS, events are used in four ways:

1) they are used to reconstitute aggregate state
2) they are used to build read model
3) they are used to drive back-end workflows
4) they can be used as audit log
The flow of events in ES model is:
You can use standard approach of working with tables representing state of aggregates, or whatever persistence approach is in place,
But still want to use last two advantages of events:
3) they are used to drive back-end workflows
4) they can be used as audit log

So you can design the system as follows:
Here event log can be used as audit trail, and sagas can be driven by events,
You can also archive events from event log periodically, thus you don't need anymore to store all events all the time

Friday, August 26, 2016

CQRS Application Building Blocks

From time to time I try to rethink the architecture of an application I work on, do some sanity check, find hidden things which were not realized before, make them explicit.

During last such procedure, I have identified the following building blocks for CQRS app.

CQRS application consists of at least several independently running processes, 
There are 
- a process for making action on business domain
- a reaction to that action through backend workflow process (hosting sagas or process managers)
- a separate process for building a read model

You want to be able to easily host those independent functionalities in one or more processes, configure them to work cooperatively, and do this in response to business needs - there are different clients, many bounded contexts, many environments, many infrastructure variations

So the pain I was feeling is how to effectively bootstrap a process and explain it how to cooperate with other processes in a big picture.

At this stage I identified four groups for functional units I call features or modules.

Those groups are:
- kernel
- context specific 
- infrastructure
- host

In kernel there are the following features (building blocks)
- event
- domain (depends on event)
- event provider (depends on event)
- query
- projection (depends on event, event provider and query)
- api
- scheduler (depends on event)
- saga (depends on event, event provider, domain and scheduler)

kernel is not bound to any infrastructure
every feature is implemented with some class inheriting abstract module, and module instance is responsible for doing feature specific task relying on abstractions
(for example domain feature provides Engine, which can execute commands)

context specific group has different number of blocks from context to context, but they can be
- context domain (defines aggregates, and commands/events)
- context query (defines query schema)
- context projection (defines what events from context domain to project to what schema from query)
- context api (exposes UI-specific api, relying on context domain and context query)
- context saga (implements business processes relying on context domain, references context query as well)

infrastructure layer implements abstractions used by features in kernel, and may be (this is an example):
- sql server event store
- katana self hosted web api
- sql server query
- sql server scheduler
- sql server event provider

there may be more than one infrastructure for each feature (kernel module)

and last big group - hosts, hosts are separately hostable services bootstrapping set of functions they host, they may bootstrap a  lot of endpoints in a single process or in many separate processes. The typical hosts can be:
- api host (uses katana web api,  sql server event store and sql server query for context api which relies on context domain and context query)
- projection worker host (uses sql server event provider, sql server query, context domain events, context query, context projection)
- saga worker host (uses sql server event store, event provider, scheduler and query, with context saga etc)

So there are small features in kernel, they will be reused between many contexts.
Context features and kernel features have no knowledge of infrastructure, the difference between context features and kernel features is - context features implement context specific program logic, while kernel features provide base classes for doing that.

Infrastructure modules also does not need to be coded from context to context, they can be reused, but the infrastructure implements abstractions for kernel, so one context can use one infrastructure while another can use another.

Hosts are the central bootstrappers where you can decide (in one simple class), 
- which context modules you host in this process
- which kernel feature abstractions they rely on, and provide infrastructure implementations for those
- provide configuration for this (ports, connection strings, other context connection details etc)

Wednesday, March 30, 2016

Generate C# Code for Google Protobuf Definition in VS 2015

I created small extension for Visual Studio 2015, allowing to write .proto files with Google Protobuf definitions, and generating C# code on save. The extension is really a custom tool for .proto files.

The code is available on github

To use it - 
- clone the repo, 
- build the solution

- navigate to bin\Debug\ and run ProtobufCSharp.vsix

- run Visual Studio 2015, and enjoy