Coder Social home page Coder Social logo

event-driven-dotnet / eventdriven.referencearchitecture Goto Github PK

View Code? Open in Web Editor NEW
64.0 8.0 11.0 509 KB

Reference architecture for using EventDriven abstractions and libraries for Domain Driven Design (DDD), Command-Query Responsibility Segregation (CQRS) and Event Driven Architecture (EDA).

License: MIT License

C# 96.75% Gherkin 3.25%
domain-driven-design cqrs ddd event-driven eda event-bus microservices

eventdriven.referencearchitecture's Introduction

EventDriven.ReferenceArchitecture

Reference architecture for using Event Driven .NET abstractions and libraries for Domain Driven Design (DDD), Command Query Responsibility Segregation (CQRS) and Event Driven Architecture (EDA).

Prerequisites

Introduction

This project builds on the principles of Domain Driven Design (DDD) to provide a set of abstractions and reference architecture for implementing the Command Query Responsibility Segregation (CQRS) pattern. By providing an event bus abstraction over Dapr (Distributed Application Runtime), the reference architecture demonstrates how to apply principles of Event Driven Architecture (EDA). Because entities process commands by emitting domain events, adding event sourcing at a later time will be relatively straightforward.

Note: EventDriven.CQRS.Abstractions version 2.0 or later uses MediatR to enable a handler per command pattern with behaviors for cross-cutting concerns.

The Reference Architecture projects demonstrate how to apply these concepts to two microservices: CustomerService and OrderService. In addition, each service has separate controllers for read and write operations, thus segregating command and query responsibilities, with different sets of models, or Data Transfer Objects (DTO's).

  • Command Controller: Converts DTO's to domain entities using AutoMapper. Passes commands to a command broker, which selects the appropriate command handler for executing business logic.
  • Command Handlers: Uses a domain entity to process commands which generate one or more domain events, then requests entity to apply the domain events in order to mutate entity state. Persists entity state using a repository abstraction and optionally publishes an integration event which is handled by another microservice.
  • Query Controller: Passes queries to a query broker, which selects the appropriate query handler to retrieve entities. Converts entities to DTO's with AutoMapper.
  • Query Handlers: Processes queries to retrieve entities using a repository abstraction.
  • Behaviors: Used to implement cross-cutting concerns such as logging or validation.
  • Repository: Used to persist or retrieve entities from a database.
  • Event Bus: Used to publish integration events, as well as subscribe to events using an event handler. Dapr is used to abstract away the underlying pub/sub implementation. The default is Redis (for local development), but Dapr can be configured to use other components, such as AWS SNS+SQS.

Note: This example illustrates a simple CQRS implementation with a shared database and single service for both read and write operations. A more sophisticated implementation might entail separate services and databases for read and write operations, using integration events to communicate between them. This simple example only uses integration events to communicate between the customer and order services.

Running Services with Aspire

  1. If using an IDE such as Visual Studio or Rider, Using an IDE such as Visual Studio or Rider, run the http profile of ReferenceArchitecture.AppHost.
  2. Open the Aspire dashboard to inspect service endpoints and view logs.
  3. Create some customers.
    • Open http://localhost:5656/swagger
    • Execute posts using contents of customers.json.
    • Copy post response, modify fields, then execute puts.
      • Make sure to copy etag value from last response, or you will get a concurrency error.
    • Copy id and etag values to execute deletes.
    • Execute gets to retrieve customers.
    • View customers database collections using Robo 3T.
  4. Create some orders.
    • Open http://localhost:5757/swagger
    • Execute posts using contents of orders.json.
    • Copy post response, modify fields, then execute puts.
      • Make sure to copy etag value from last response, or you will get a concurrency error.
    • Copy id and etag values to execute deletes.
    • Execute gets to retrieve orders.
    • View orders database collections using Robo 3T.
  5. Update the address of a customer who has order.
    • Note the address is also updated for the customer's orders.
    • Observe log messages in terminal when integration events are published and handled.

Running Services with the Dapr CLI

  1. Start the Customer Service using the Dapr CLI from a terminal at the project root.

    dapr run --app-id customer-service --app-port 5656 --resources-path ../dapr/components -- dotnet run
    
  2. Start the Order Service using the Dapr CLI from a terminal at the project root.

    dapr run --app-id order-service --app-port 5757 --resources-path ../dapr/components -- dotnet run
    
  3. Open the Dapr Dashboard at http://localhost:8080

    dapr dashboard
    
  4. Execute steps 3-5 above to use services and pub-sub features.

Running Tests

Unit Tests

In the test folder you'll find unit tests for both CustomerService and OrderService projects.

  • xUnit is used as the unit testing framework.
  • Moq is used as the mocking framework.

Note: Because database API's are notoriously difficult to mock, repositories are deliberately excluded from unit testing. Instead, repositories attain code coverage with acceptance/integration tests.

  1. Run unit CustomerService.Tests and OrderService.Tests from the Test explorer in your IDE.
  2. Alternatively, open a terminal at CustomerService.Tests and OrderService.Tests, then run dotnet test

Acceptance (Integration) Tests

In the tests folder you'll find an EventDriven.ReferenceArchitecture.Specs project with automated acceptance / integration tests.

  1. Using an IDE such as Visual Studio or Rider, run the specs profile of ReferenceArchitecture.AppHost.
  2. Run EventDriven.ReferenceArchitecture.Specs from the Test explorer of your IDE.
  3. Alternatively, open a terminal at EventDriven.ReferenceArchitecture.Specs, then run dotnet test

Development Guide

For step-by-step instructions on how to build microservices with Event Driven .NET using this reference architecture, please see the Event Driven .NET Development Guide.

eventdriven.referencearchitecture's People

Contributors

jesmith026 avatar tonysneed 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

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.