Giter Club home page Giter Club logo

todomvc-ddd-cqrs-eventsourcing's Introduction

Instructions

Start

docker compose build
docker compose up

Source Code!

Being this project has such a small domain context there are only a couple source files which contain real logic. Other files are helpers, extensions, or setup.

Important backend files:

Web frontend from TodoMVC-React

What is EventSourcing?

EventSourcing is a process of representing domain objects (Orders, Invoices, Accounts, etc) as a series of separate events.

Your application ends up being 1 long audit log which records every state-changing event that occurs. The advantage of this approach is other processes can read this event log and generate models that contain only the information the process cares about. There is also additional information available that other services perhaps don't record themselves.

Imagine a shoppign cart which fills with items to buy. The warehouse only cares about the final order of the stuff the customer actually agreed to purchase -

but the marketing team might care more about the items the customer removed from their cart without buying.

Using eventsourcing correctly you can generate models which contain both sets of information to satisfy both departments with only 1 set of data.

What is CQRS

CQRS stands for Command and Query Responsibility Segregation

In a nut shell - commands are everything that want to change the application state. Queries are anything that want to read application state. There is no overlap

Commands do not return any data other than if they were Accepted or Rejected. Accepted meaning the change was saved and read models will be updated. Rejected meaning the command failed validation or was not valid to be run at this time. (One example would be trying to invoice a sales order which has already been invoiced)

Architecture Overview

Commands Processing

Good reads

EventStore Management

{host}:2113

RabbitMq Management

{host}:15672

todomvc-ddd-cqrs-eventsourcing's People

Contributors

charlessolar avatar dependabot[bot] avatar galenp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

todomvc-ddd-cqrs-eventsourcing's Issues

Change example; mention idempotency

(One example would be trying to invoice a sales order twice)

I'd suggest changing this to editing a sales order that has already been invoiced. In general, as I'm sure you are aware, command processing is best designed in such a way that the processing of a command generally be idempotent in nature - so if it is the same request (e.g. bearing the same originating requestor's requestId guid), the second request should also return a HTTP Accepted response rather than something like Conflict or a 400

What would a UnitTest for ToDo look like?

I really like Aggregates.NET compared to all the other DDD/ES/CQRS libraries and examples I've seen. It's by far the cleanest and most thorough implementation.

I've been working through this example app and It's a decent primer, just missing a sample of unit tests for ToDo.

I was going to take a crack and setting some up myself, but several of the Interfaces and Classes I would use (based on Aggregates.NET.UnitTests Test class) are internal and thus I'm a bit stumped.

I'd be happy to submit a pull request to add the UnitTests for ToDo but I'm stalled.

The configuration is invalid. Creating the instance for type IDisposable failed. The given type IContainer is not a concrete type.

I can not get it working because Application project throws the exception. Please help sort this out.

[Fatal] <Unhandled> Unhandled exception
2022-01-24T14:51:58.429887154Z System.AggregateException: One or more errors occurred. (The configuration is invalid. Creating the instance for type IDisposable failed. The given type IContainer is not a concrete type. Please use one of the other overloads to register this type. Verification was triggered because Container.Options.EnableAutoVerification was enabled. To prevent the container from being verified on first resolve, set Container.Options.EnableAutoVerification to false.)
2022-01-24T14:51:58.429906836Z  ---> SimpleInjector.ActivationException: The configuration is invalid. Creating the instance for type IDisposable failed. The given type IContainer is not a concrete type. Please use one of the other overloads to register this type. Verification was triggered because Container.Options.EnableAutoVerification was enabled. To prevent the container from being verified on first resolve, set Container.Options.EnableAutoVerification to false.
2022-01-24T14:51:58.429911150Z  ---> System.InvalidOperationException: The configuration is invalid. Creating the instance for type IDisposable failed. The given type IContainer is not a concrete type. Please use one of the other overloads to register this type.
2022-01-24T14:51:58.429914117Z  ---> SimpleInjector.ActivationException: The given type IContainer is not a concrete type. Please use one of the other overloads to register this type.
2022-01-24T14:51:58.429916775Z    at SimpleInjector.Advanced.DefaultConstructorResolutionBehavior.VerifyTypeIsConcrete(Type implementationType)
2022-01-24T14:51:58.429919403Z    at SimpleInjector.Advanced.DefaultConstructorResolutionBehavior.TryGetConstructor(Type implementationType, String& errorMessage)
2022-01-24T14:51:58.429921993Z    at SimpleInjector.ConstructorResolutionBehaviorExtensions.GetConstructor(IConstructorResolutionBehavior behavior, Type implementationType)
2022-01-24T14:51:58.429924582Z    at SimpleInjector.ContainerOptions.SelectConstructor(Type implementatioType)
2022-01-24T14:51:58.429926954Z    at SimpleInjector.Registration.BuildNewExpression()
2022-01-24T14:51:58.429929215Z    at SimpleInjector.Registration.BuildTransientExpression()
2022-01-24T14:51:58.429931505Z    at SimpleInjector.Lifestyles.SingletonLifestyle.SingletonRegistration.GetInterceptedInstanceWithNullCheck()
2022-01-24T14:51:58.429935198Z    at SimpleInjector.Lifestyles.SingletonLifestyle.SingletonRegistration.GetInterceptedInstance()
2022-01-24T14:51:58.429937648Z    at SimpleInjector.Lifestyles.SingletonLifestyle.SingletonRegistration.BuildExpression()
2022-01-24T14:51:58.429940137Z    at SimpleInjector.InstanceProducer.BuildExpressionInternal()
2022-01-24T14:51:58.429942452Z    at SimpleInjector.Internals.LazyEx`1.InitializeAndReturn()
2022-01-24T14:51:58.429944811Z    at SimpleInjector.InstanceProducer.BuildExpression()
2022-01-24T14:51:58.429947142Z    at SimpleInjector.InstanceProducer.VerifyExpressionBuilding()
2022-01-24T14:51:58.429949455Z    --- End of inner exception stack trace ---
2022-01-24T14:51:58.429951812Z    at SimpleInjector.InstanceProducer.VerifyExpressionBuilding()
2022-01-24T14:51:58.429954288Z    at SimpleInjector.Container.VerifyThatAllExpressionsCanBeBuilt(InstanceProducer[] producersToVerify)
2022-01-24T14:51:58.429956912Z    at SimpleInjector.Container.VerifyThatAllExpressionsCanBeBuilt()
2022-01-24T14:51:58.429959293Z    at SimpleInjector.Container.VerifyInternal(Boolean suppressLifestyleMismatchVerification)
2022-01-24T14:51:58.429964546Z    at SimpleInjector.Container.Verify(VerificationOption option)
2022-01-24T14:51:58.429967109Z    at SimpleInjector.Container.Verify()
2022-01-24T14:51:58.429969408Z    at SimpleInjector.Container.NotifyAndLock()
2022-01-24T14:51:58.429971701Z    --- End of inner exception stack trace ---
2022-01-24T14:51:58.429973905Z    at SimpleInjector.Container.NotifyAndLock()
2022-01-24T14:51:58.429976128Z    at SimpleInjector.Container.GetInstance(Type serviceType)
2022-01-24T14:51:58.429978430Z    at Aggregates.Internal.Container.Resolve(Type resolve) in C:\projects\aggregates-net\src\Aggregates.NET.SimpleInjector\Internal\Container.cs:line 119
2022-01-24T14:51:58.429981595Z    at Aggregates.Internal.ContainerAdapter.Build(Type typeToBuild) in C:\projects\aggregates-net\src\Aggregates.NET.NServiceBus\Internal\ContainerAdapter.cs:line 70
2022-01-24T14:51:58.429986890Z    at NServiceBus.Pipeline.RegisterStep.CreateBehavior(IBuilder defaultBuilder)
2022-01-24T14:51:58.429989447Z    at NServiceBus.Pipeline`1.<>c__DisplayClass0_0.<.ctor>b__0(RegisterStep r)
2022-01-24T14:51:58.429992072Z    at System.Linq.Enumerable.SelectListIterator`2.ToArray()
2022-01-24T14:51:58.429994319Z    at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
2022-01-24T14:51:58.429996797Z    at NServiceBus.Pipeline`1..ctor(IBuilder builder, PipelineModifications pipelineModifications)
2022-01-24T14:51:58.429999151Z    at NServiceBus.PipelineComponent.CreatePipeline[T](IBuilder builder)
2022-01-24T14:51:58.430001424Z    at NServiceBus.SendComponent.CreateMessageOperations(IBuilder builder, PipelineComponent pipelineComponent)
2022-01-24T14:51:58.430003919Z    at NServiceBus.StartableEndpoint.Start()
2022-01-24T14:51:58.430006526Z    at NServiceBus.HostingComponent.Start(IStartableEndpoint startableEndpoint)
2022-01-24T14:51:58.430009043Z    at NServiceBus.ExternallyManagedContainerHost.Start(IBuilder externalBuilder)
2022-01-24T14:51:58.430011437Z    at Aggregates.Bus.Start(IStartableEndpointWithExternallyManagedContainer nsb) in C:\projects\aggregates-net\src\Aggregates.NET.NServiceBus\Bus.cs:line 32
2022-01-24T14:51:58.430014115Z    at Aggregates.Configuration.Start() in C:\projects\aggregates-net\src\Aggregates.NET\Configure.cs:line 48
2022-01-24T14:51:58.430016574Z    at Example.Program.InitBus() in /src/Application/Endpoint.cs:line 104
2022-01-24T14:51:58.430018990Z    --- End of inner exception stack trace ---
2022-01-24T14:51:58.430021192Z    at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
2022-01-24T14:51:58.430023644Z    at System.Threading.Tasks.Task`1.get_Result()
2022-01-24T14:51:58.430025948Z    at Example.Program.Main(String[] args) in /src/Application/Endpoint.cs:line 61

Webpack 4 upgrade

Upgrade webpack to 4 and investigate use of new / changed features

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.