CQRS & Event SourcingAn alternative architecture for DDDDennis Doomen
The default architectureA better architectureThe alternative architectureAdvanced topics Contents
The Default ArchitectureEasy to buildAccepted by managementWell knownLots of resourcesLots of frameworksSilverlight ApplicationNo concurrencyScalability limitedNo domain verbsGranularity DTOsUnneccesary DTO conversionsConflicting demandsProxyDTOsServicesDomain ServicesDomain ModelRepositoriesUnit of WorkService AgentsRelationalDatabaseBackoffice Systems
CQRSSilverlight ApplicationCommands are verbsNo DTO conversionEasy to build disconnected clientsQuery Store = No SQLVery scalableService AgentQueriesBusiness ActionsDTOsCommandsCommand ServiceQuery ServiceCommand HandlersDomain ServicesDomain ModelData Access LayerRepositoriesUoWService AgentsDifficult to sync databaseNo concurrencyRequires a task-based UIComplexityRelationalDatabaseQuery StoreBackoffice SystemsChangesQuery Store
Task-based UIs a.k.a. Inductive UIs answer:What am I supposed to do now?Where do I go from here to accomplish my task?Task-based UIs
Focus screens on single taskMake the task’s intention clearOffer links to secondary tasksProvide screens for starting tasksMake the next step obviousFrom Microsoft Inductive User Interface GuidelinesGuidelines for Task-based UIs
Are valid or not, regardless of contextNamed in Ubiquitous LanguageState intentCan be asynchronous......but beware of eventual consistencyRejection via exception or fault eventCommands
One table per UI viewExposed through SOA-style web servicesWCF data servicesWCF RIA ServicesCan be anythingRelational DatabaseNo SQL databaseXML filesQuery Store
CQRS & Event SourcingSilverlight ApplicationGreat performanceConflict MergingHistorical TrackingTrival SynchronizationEasy IntegrationIndependent Query Store QueriesService AgentBusiness ActionsCommandsDTOsCommand ServiceCommand HandlersDomain ServicesDomain ModelEventsQuery ServiceDenormalizerEventsEvent HandlersLots of new conceptsNot so acceptableFew resourcesNo consensus yetMore complexityAggregate boundaries importantData Access LayerUoWEvent BusDomain RepositoryService AgentsQuery StoreEvent StoreQuery StoreBackoffice SystemsEvents
Represent state changes in aggregate rootNamed in passed tenseUsing Ubiquitous LanguageEntire aggregate is stored in serialized formatEvents never changeSnapshots to improve performanceEvents
Have no relationships (!)Communicate through eventsEntities do not expose setters (!)Apply events to themselvesState exposed as mementosAggregate Roots
Conflict Merging
Event Schema Versioning- Adds missing properties- Renames renamed properties- Converts valuesPost ConverterProperty Bag ConverterPost ConverterPost Converterid = 123SQL ServerDomain RepositoryEvent StorePropertyBagGet(id = 123)Eventid = 123
Event Store != relational database...so no unique constraintsWorkaroundsCheck uniqueness through query sideAdd generic unique column to event storeIntroduce a parent that enforces uniquenessUnique Constraints
The CQRS KitchenViews (XAML + C#)View ModelsApplication ServicesUnityService AgentCommandsDTOsCommand ServiceCommand HandlersWCFDomain ServicesMementosDomain ModelUnityEnterprise Library 5NCQRS++NSerivceBusEventsEvent HandlersEvent BusDomain RepositoryEventsUoWEvent StoreQuery ServiceDenormalizersWCF Data ServicesThin Data Access LayerEntity Framework 4SQL ServerEntity Framework 4SQL Server
NCQRSThe CQRS framework for .NET http://ncqrs.codeplex.com/Very promisingGreat DocumentationQuality codeUses Code ContractsVery active teamI’m considering joining (Still) difficult to get startedNot proven yetNot complete yetFeels a bit too complexNot everything is pluggableMisses a coding standard
In summaryGreat for performanceVery scalableSupports historical auditingSupports high concurrencyEasy to integrate with other systemsVery testable with TDD/DDDAligns great with Ubiquitous LanguageDoesn’t require expensive RDBMSLots of new conceptsLots of choices to makeNot yet accepted by managementLimited documentationNo consensus yetMore complexityAggregate design is importantI haven’t found all issues yet
Background InformationGreg Young, Mark Nijhof, Udi Dahan, Jonathan OliverExample Code, FrameworksThe CQRS Kitchen, NCQRSInteraction Design / Task-Based UIsThe Inmates Are Running The Asylum, Alan CooperMicrosoft Inductive User Interface GuidelinesLinks
Emaildennis.doomen@avivasolutions.nlTwitterddoomenBlogwww.dennisdoomen.netQuestions?

CQRS and Event Sourcing, An Alternative Architecture for DDD

  • 1.
    CQRS & EventSourcingAn alternative architecture for DDDDennis Doomen
  • 2.
    The default architectureAbetter architectureThe alternative architectureAdvanced topics Contents
  • 3.
    The Default ArchitectureEasyto buildAccepted by managementWell knownLots of resourcesLots of frameworksSilverlight ApplicationNo concurrencyScalability limitedNo domain verbsGranularity DTOsUnneccesary DTO conversionsConflicting demandsProxyDTOsServicesDomain ServicesDomain ModelRepositoriesUnit of WorkService AgentsRelationalDatabaseBackoffice Systems
  • 4.
    CQRSSilverlight ApplicationCommands areverbsNo DTO conversionEasy to build disconnected clientsQuery Store = No SQLVery scalableService AgentQueriesBusiness ActionsDTOsCommandsCommand ServiceQuery ServiceCommand HandlersDomain ServicesDomain ModelData Access LayerRepositoriesUoWService AgentsDifficult to sync databaseNo concurrencyRequires a task-based UIComplexityRelationalDatabaseQuery StoreBackoffice SystemsChangesQuery Store
  • 5.
    Task-based UIs a.k.a.Inductive UIs answer:What am I supposed to do now?Where do I go from here to accomplish my task?Task-based UIs
  • 6.
    Focus screens onsingle taskMake the task’s intention clearOffer links to secondary tasksProvide screens for starting tasksMake the next step obviousFrom Microsoft Inductive User Interface GuidelinesGuidelines for Task-based UIs
  • 7.
    Are valid ornot, regardless of contextNamed in Ubiquitous LanguageState intentCan be asynchronous......but beware of eventual consistencyRejection via exception or fault eventCommands
  • 8.
    One table perUI viewExposed through SOA-style web servicesWCF data servicesWCF RIA ServicesCan be anythingRelational DatabaseNo SQL databaseXML filesQuery Store
  • 9.
    CQRS & EventSourcingSilverlight ApplicationGreat performanceConflict MergingHistorical TrackingTrival SynchronizationEasy IntegrationIndependent Query Store QueriesService AgentBusiness ActionsCommandsDTOsCommand ServiceCommand HandlersDomain ServicesDomain ModelEventsQuery ServiceDenormalizerEventsEvent HandlersLots of new conceptsNot so acceptableFew resourcesNo consensus yetMore complexityAggregate boundaries importantData Access LayerUoWEvent BusDomain RepositoryService AgentsQuery StoreEvent StoreQuery StoreBackoffice SystemsEvents
  • 10.
    Represent state changesin aggregate rootNamed in passed tenseUsing Ubiquitous LanguageEntire aggregate is stored in serialized formatEvents never changeSnapshots to improve performanceEvents
  • 11.
    Have no relationships(!)Communicate through eventsEntities do not expose setters (!)Apply events to themselvesState exposed as mementosAggregate Roots
  • 12.
  • 13.
    Event Schema Versioning-Adds missing properties- Renames renamed properties- Converts valuesPost ConverterProperty Bag ConverterPost ConverterPost Converterid = 123SQL ServerDomain RepositoryEvent StorePropertyBagGet(id = 123)Eventid = 123
  • 14.
    Event Store !=relational database...so no unique constraintsWorkaroundsCheck uniqueness through query sideAdd generic unique column to event storeIntroduce a parent that enforces uniquenessUnique Constraints
  • 15.
    The CQRS KitchenViews(XAML + C#)View ModelsApplication ServicesUnityService AgentCommandsDTOsCommand ServiceCommand HandlersWCFDomain ServicesMementosDomain ModelUnityEnterprise Library 5NCQRS++NSerivceBusEventsEvent HandlersEvent BusDomain RepositoryEventsUoWEvent StoreQuery ServiceDenormalizersWCF Data ServicesThin Data Access LayerEntity Framework 4SQL ServerEntity Framework 4SQL Server
  • 16.
    NCQRSThe CQRS frameworkfor .NET http://ncqrs.codeplex.com/Very promisingGreat DocumentationQuality codeUses Code ContractsVery active teamI’m considering joining (Still) difficult to get startedNot proven yetNot complete yetFeels a bit too complexNot everything is pluggableMisses a coding standard
  • 17.
    In summaryGreat forperformanceVery scalableSupports historical auditingSupports high concurrencyEasy to integrate with other systemsVery testable with TDD/DDDAligns great with Ubiquitous LanguageDoesn’t require expensive RDBMSLots of new conceptsLots of choices to makeNot yet accepted by managementLimited documentationNo consensus yetMore complexityAggregate design is importantI haven’t found all issues yet
  • 18.
    Background InformationGreg Young,Mark Nijhof, Udi Dahan, Jonathan OliverExample Code, FrameworksThe CQRS Kitchen, NCQRSInteraction Design / Task-Based UIsThe Inmates Are Running The Asylum, Alan CooperMicrosoft Inductive User Interface GuidelinesLinks
  • 19.

Editor's Notes

  • #4 DisadvantagesNo concurrency; conflicting service requests are simply rejectedStaleness ignored;Scalability limited; No domain verbs; domain model does contain concepts from the domain model, just not the business actionsGranularity DTOs; What operations to expose in your WCF service? What relations to include and when? What domain entities to flatten.Unneccesary DTO conversions; Conversions from/to domain model entities, traversing of relations, eager fatchingConflicting demands; query demands denormalized schema, commands require normalized integer schema
  • #5 DisadvantagesNo concurrency; conflicting service requests are simply rejectedStaleness ignored;Scalability limited; No domain verbs; domain model does contain concepts from the domain model, just not the business actionsGranularity DTOs; What operations to expose in your WCF service? What relations to include and when? What domain entities to flatten.Unneccesary DTO conversions; Conversions from/to domain model entities, traversing of relations, eager fatchingConflicting demands; query demands denormalized schema, commands require normalized integer schema
  • #8 Commands validate itself without using any context, thus is valid or not instead of sometimes.Commands are named in the Ubiquitous LanguageCommands can be send asynchronously, and thus can be resistent to database unavailabilityMogelijk meerdere commands met dezeflde state change: CorrectCustomerAddress, MoveCustomerCommand interfaces: in-memory, WCF, WCF RIA Services, NServiceBus, etc
  • #10 DisadvantagesNo concurrency; conflicting service requests are simply rejectedStaleness ignored;Scalability limited; No domain verbs; domain model does contain concepts from the domain model, just not the business actionsGranularity DTOs; What operations to expose in your WCF service? What relations to include and when? What domain entities to flatten.Unneccesary DTO conversions; Conversions from/to domain model entities, traversing of relations, eager fatchingConflicting demands; query demands denormalized schema, commands require normalized integer schema
  • #16 DisadvantagesNo concurrency; conflicting service requests are simply rejectedStaleness ignored;Scalability limited; No domain verbs; domain model does contain concepts from the domain model, just not the business actionsGranularity DTOs; What operations to expose in your WCF service? What relations to include and when? What domain entities to flatten.Unneccesary DTO conversions; Conversions from/to domain model entities, traversing of relations, eager fatchingConflicting demands; query demands denormalized schema, commands require normalized integer schema