About • Tech Stacks & Research • The Solution Architecture • How to run • References
This project was built as a learning to understand the concept of the **Clean Architecture** together with
Entity FrameworkCore as ORM and MediatR as CQRS library. The intend purpose was to build a simple store application,
where you can store and manage the products as an administrator, and able to order, online payment as the client.
Service | Description |
---|---|
Customer | Managing customers |
Order | Managing order processing |
Product | Managing product items |
Payment | Managing payment |
- AspNetCore 8 WebAPI (using Minimal API)
- SwaggerUI
- API Versioning
- Onion architecture
- Authentication
- Testing
- Caching
- Logging
- Performance
- Mapping (AutoMapper)
- Background Jobs
- Exception Handling
- Code First Approach
- Dependency injection
- CRQS with MediatR library
- MediatR pipelines for: Caching, Validation, Logging
- Repository pattern
- Option pattern
- Dockerized
- CI/CD
- Kubernetes
Async Projections
In a Command and Query Responsibility Segregation (CQRS) system, denormalized asynchronous projections can significantly improve performance for several reasons:
-
Improved Read Performance: In a CQRS system, the read side is separate from the write side and is optimized for querying data. By denormalizing the data in the projections, the read side can access the data it needs more efficiently, reducing the number of joins required to retrieve data and ultimately speeding up query performance.
-
Reduced Latency: When data is denormalized, it's usually stored in a format that's more suitable for the specific use case. This can reduce the amount of data that needs to be retrieved from the database, which can help to minimize latency and improve the overall responsiveness of the system.
-
Increased Scalability: Denormalized projections can handle a larger volume of data more efficiently than normalized ones. This is because denormalized data is usually stored in a format that's optimized for a specific use case, which allows the system to process the data more quickly and with less resources.
-
Simpler Architecture: In a normalized data model, data is often spread out across multiple tables, which can make the system more complex to design, develop, and maintain. By denormalizing the data, it can be easier to manage and understand, which can simplify the overall architecture and make the system more maintainable.
-
Improved Concurrency: Asynchronous projections allow multiple operations to be performed at the same time and, denormalized projections reduce contention, helping to improve concurrent write operation performance.
In summary, denormalized asynchronous projections in a CQRS system can help to improve performance by reducing latency, increasing scalability, simplifying the architecture, and improving concurrency. This results in a more responsive and efficient system that can handle larger volumes of data and more complex queries.
Snapshotting
Snapshotting is an optimisation that reduces time spent on reading event from an event store.
Gunia, Kacper. "Event Sourcing: Snapshotting", domaincentric.net, last edited on 5 Jun 2020
More details in snapshot section.
Minimize Exceptions
Exceptions should be rare. Throwing and catching exceptions is slow relative to other code flow patterns. Because of this, exceptions shouldn't be used to control normal program flow.
Recommendations:
- Do not use throwing or catching exceptions as a means of normal program flow, especially in hot code paths.
- Do include logic in the app to detect and handle conditions that would cause an exception.
- Do throw or catch exceptions for unusual or unexpected conditions.
- App diagnostic tools, such as Application Insights, can help to identify common exceptions in an app that may affect performance.
"ASP.NET Core Performance Best Practices" MSDN, Microsoft Docs, last edited on 18 Fev 2022
Pool HTTP connections with HttpClientFactory
Closed
HttpClient
instances leave sockets open in theTIME_WAIT
state for a short period of time. If a code path that creates and disposes ofHttpClient
objects is frequently used, the app may exhaust available sockets.Recommendations:
- Do not create and dispose of HttpClient instances directly.
- Do use HttpClientFactory to retrieve HttpClient instances.
"ASP.NET Core Performance Best Practices" MSDN, Microsoft Docs, last edited on 18 Fev 2022
DbContext Pooling
The basic pattern for using EF Core in an ASP.NET Core application usually involves registering a custom DbContext type into the dependency injection system and later obtaining instances of that type through constructor parameters in controllers. This means a new instance of the DbContext is created for each request.
In version 2.0 we are introducing a new way to register custom DbContext types in dependency injection which transparently introduces a pool of reusable DbContext instances. This is conceptually similar to how connection pooling operates in ADO.NET providers and has the advantage of saving some of the cost of initialization of DbContext instance.
"New features in EF Core 2.0" MSDN, Microsoft Docs, last edited on 11 Oct 2020
Clone the repository git clone https://github.com/luuthuong/eshop-microservices
In root directory
dotnet run --project .\src\ProductSyncService\ProductSyncService.API
Or docker: docker compose up --build
- Effective Aggregate Design Part I: Modeling a Single Aggregate
- Effective Aggregate Design Part II: Making Aggregates Work Together
- Effective Aggregate Design Part III: Gaining Insight Through Discovery
- CQRS Documents - Greg Young
- Versioning in an Event Sourced - Greg Young
- Clarified CQRS - Udi Dahan
- Event-driven IO - Oskar Dudycz
- Code Opinion - Derek Comartin
- Domain Centric - Kacper Gunia
- CQRS Event Sourcing - Daniel Whittaker
- Event Store - Alexey Zimarev
- Mathias Verraes Student of Systems
- Modeling Uncertainty with Reactive DDD - Vaughn Vernon
- Reactive DDD—When Concurrent Waxes Fluent - Vaughn Vernon
- Pattern: Event sourcing - Chris Richardson
- Clarified CQRS - Udi Dahan
- Udi & Greg Reach CQRS Agreement
- Event Sourcing and CQRS - Alexey Zimarev
- What is Event Sourcing? - Alexey Zimarev
- Distilling the CQRS/ES Capability - Vijay Nair
- Dispelling the Eventual Consistency FUD when using Event Sourcing - Vijay Nair
- Why would I need a specialized Event Store? - Greg Woods
- A Fast and Lightweight Solution for CQRS and Event Sourcing - Daniel Miller
- Event Sourcing: The Good, The Bad and The Ugly - Dennis Doomen
- What they don’t tell you about event sourcing - Hugo Rocha
- Event Sourcing pattern - MSDN
- CQRS + Event Sourcing, Step by Step - Daniel
- Architectural considerations for event-driven microservices-based systems - Tanmay Ambre
- How messaging simplifies and strengthens your microservice application - Callum Jackson
- Event Sourcing: Aggregates Vs Projections - Kacper Gunia
- Event Sourcing: Projections - Kacper Gunia
- Advantages of the event-driven architecture pattern - Grace Jansen & Johanna Saladas