Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Dutch .NET Group Meetup - Building an event sourced system in .NET

Dutch .NET Group Meetup - Building an event sourced system in .NET

In this talk I will show how we are building a large ERP system in .NET, using CQRS and event sourcing. We will talk about the good stuff (modularization, scalability), the lessons learned (eventual consistency) and the challenges ahead (upgrades).

Michiel Overeem

April 19, 2018
Tweet

More Decks by Michiel Overeem

Other Decks in Technology

Transcript

  1. 20 years of ERP 10.000 customers 90% cloud Person Entity

    Customer Role Order Agreement party Spending limit Address Organisation Entity Delivery BusinessAc tivity party Invoice BusinessAc tivity party Address Address Spending limit Spending limit Own Organisation Workarea workarea Spending limit Put all our knowledge and experience in a model
  2. Customized Web Scalable CQRS Event sourcing Person Entity Customer Role

    Order Agreement party Spending limit Address Organisation Entity Delivery BusinessAc tivity party Invoice BusinessAc tivity party Address Address Spending limit Spending limit Own Organisation Workarea workarea Spending limit
  3. Command Query Responsibility Segregation Client Command system Query system Eventing

    system “PlaceOrderCommand”: { “OrderId”: “0b81b458-7671-4e9b-844b-9934255f5406”, “CustomerName”: “Linus Torvalds”, “OrderLines”: [ … ] }
  4. Command Query Responsibility Segregation Client Command system Query system Eventing

    system “GetOrders”: { “CustomerName”: “Linus Torvalds”, }
  5. DDD

  6. Aggregates “PlaceOrderCommand”: { “OrderId”: “0b81b458-7671-4e9b-844b-9934255f5406”, “CustomerName”: “Linus Torvalds”, “OrderLines”: [

    … ] } “OrderPlacedEvent”: { “OrderId”: “0b81b458-7671-4e9b-844b-9934255f5406”, “CustomerName”: “Linus Torvalds”, “OrderLines”: [ … ] }
  7. T

  8. CQRS Client Command system Query system Eventing system What is

    the data model used in the command side?
  9. Event Store StreamId Stream Revision PayloadItemName Payload StreamType Sequence Number

    CommitTime AccountId Person1 1 PersonCreatedEvent { … } Person 1 … … Person1 2 PersonUpdatedEvent { … } Person 2 … … Person2 1 PersonCreatedEvent { … } Person 3 … … Order1 1 OrderCreatedEvent { … } Order 1 … … Order2 1 OrderCreatedEvent { … } Order 2 … … Order3 1 OrderCreatedEvent { … } Order 3 … …
  10. Aggregates loading Event Store StreamId Stream Revision PayloadItemName Payload StreamType

    Sequence Number CommitTime AccountId Person1 1 PersonCreatedEvent { … } Person 1 … … Person1 2 PersonUpdatedEvent { … } Person 2 … … Person2 1 PersonCreatedEvent { … } Person 3 … … Order1 1 OrderCreatedEvent { … } Order 1 … … Order2 1 OrderCreatedEvent { … } Order 2 … … Order3 1 OrderCreatedEvent { … } Order 3 … …
  11. Event processing Event Store StreamId Stream Revision PayloadItemName Payload StreamType

    Sequence Number CommitTime AccountId Person1 1 PersonCreatedEvent { … } Person 1 … … Person1 2 PersonUpdatedEvent { … } Person 2 … … Person2 1 PersonCreatedEvent { … } Person 3 … … Order1 1 OrderCreatedEvent { … } Order 1 … … Order2 1 OrderCreatedEvent { … } Order 2 … … Order3 1 OrderCreatedEvent { … } Order 3 … …
  12. Event Sourcing A B A E C D D F

    B B A C C G H D A B C A D A A A A A A B B C C 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 1 1 2 1 1 2 3 4 5 1 1 2 1 2
  13. Event Sourcing A B A E C D D F

    B B A C C G H D A B C A D A A A A A A B B C C 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 1 1 2 1 1 2 3 4 5 1 1 2 1 2 Sequencenumbers for projectors
  14. Event Sourcing A B A E C D D F

    B B A C C G H D A B C A D A A A A A A B B C C 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 1 1 2 1 1 2 3 4 5 1 1 2 1 2 Revisions for aggregate loading and concurrency control
  15. Projection A helper-table with customer info A table for the

    projection A customer update could mean that we need to update 1.000.000+ rows
  16. Projection: joins A table with customer info A table for

    the projection A query should join the two tables.
  17. Projection: duplication A table with customer info A table with

    order info A table with customer info A table with invoice info