{"id":15653290,"url":"https://github.com/meysamhadeli/ecommerce-monolith","last_synced_at":"2025-08-25T02:11:54.895Z","repository":{"id":161572761,"uuid":"636248907","full_name":"meysamhadeli/ecommerce-monolith","owner":"meysamhadeli","description":"A monolith, built with .Net, DDD, CQRS, Vertical Slice Architecture, Event-Driven Architecture, and the latest technologies.","archived":false,"fork":false,"pushed_at":"2024-09-16T16:52:18.000Z","size":230,"stargazers_count":43,"open_issues_count":0,"forks_count":9,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-12-11T00:03:25.328Z","etag":null,"topics":["aspnetcore","clean-architecture","cqrs","ddd","docker","domain-driven-design","dotnet","dotnet-core","dotnetcore","end-to-end-testing","event-driven","integration-testing","messaging","monolith","monolith-architecture","unit-testing","vertical-slice-architecture"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/meysamhadeli.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-05-04T12:34:30.000Z","updated_at":"2024-11-26T19:41:06.000Z","dependencies_parsed_at":null,"dependency_job_id":"5cc9356c-311d-4958-8a5b-1e35a1979448","html_url":"https://github.com/meysamhadeli/ecommerce-monolith","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meysamhadeli%2Fecommerce-monolith","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meysamhadeli%2Fecommerce-monolith/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meysamhadeli%2Fecommerce-monolith/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meysamhadeli%2Fecommerce-monolith/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/meysamhadeli","download_url":"https://codeload.github.com/meysamhadeli/ecommerce-monolith/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230507051,"owners_count":18236944,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aspnetcore","clean-architecture","cqrs","ddd","docker","domain-driven-design","dotnet","dotnet-core","dotnetcore","end-to-end-testing","event-driven","integration-testing","messaging","monolith","monolith-architecture","unit-testing","vertical-slice-architecture"],"created_at":"2024-10-03T12:45:15.245Z","updated_at":"2025-08-21T10:32:11.491Z","avatar_url":"https://github.com/meysamhadeli.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🛒 ECommerce-Monolith\n\u003ca href=\"https://github.com/meysamhadeli/ecommerce-monolith/actions/workflows/ci.yml\"\u003e\u003cimg alt=\"ci-status\" src=\"https://github.com/meysamhadeli/ecommerce-monolith/actions/workflows/ci.yml/badge.svg?branch=main\u0026style=flat-square\"/\u003e\u003c/a\u003e\n\n\u003e **The primary objective of this project is to establish a framework that can facilitate the deployment and operation of a straightforward ECommerce application using cutting-edge technologies and architecture such as Vertical Slice Architecture, CQRS, and DDD in .Net.** 🚀\n\n\u003e 💡 **This project is not business-oriented and most of my focus was in the thechnical part for implement a Monolith system with a sample project.**\n\n\u003ca href=\"https://gitpod.io/#https://github.com/meysamhadeli/ecommerce-monolith\"\u003e\u003cimg alt=\"Open in Gitpod\" src=\"https://gitpod.io/button/open-in-gitpod.svg\"/\u003e\u003c/a\u003e\n\n# Table of Contents\n\n- [The Goals of This Project](#the-goals-of-this-project)\n- [Technologies - Libraries](#technologies---libraries)\n- [Structure of Project](#structure-of-project)\n- [Development Setup](#development-setup)\n  - [Dotnet Tools Packages](#dotnet-tools-packages)\n- [How to Run](#how-to-run)\n  - [Docker Compose](#docker-compose)\n  - [Documentation Apis](#documentation-apis)\n\n## The Goals of This Project\n\n- :sparkle: Implementing `Vertical Slice Architecture` at the architecture level to create a `scalable` and `maintainable` structure for the application.\n- :sparkle: Using `Domain Driven Design (DDD)` for implementing `business processes` and `validation rules`.\n- :sparkle: Adopting `CQRS` implementation with the `MediatR` library for better separation of `write` and `read` operations.\n- :sparkle: Implementing `MediatR` to `reduce coupling` and provide support for managing `cross-cutting concerns` within `pipelines`, including `validation` and `transaction handling` for the application.\n- :sparkle: Using `Postgres` as our `relational database` management system at the database level.\n- :sparkle: Incorporating `Unit Testing`, `Integration Testing`, and `End To End Testing` for testing level to ensure the `robustness` and `reliability` of the application.\n- :sparkle: Utilizing `Fluent Validation` and a `Validation Pipeline Behaviour` on top of `MediatR` to validate requests and responses and ensure `data integrity`.\n- :sparkle: Using `Minimal API` for all endpoints to create a `lightweight` and `streamlined` API.\n- :sparkle: Using `AspNetCore OpenApi` for `generating` built-in support `OpenAPI documentation` in ASP.NET Core.\n- :sparkle: Using `Docker-Compose` for our `deployment` mechanism to enable easy deployment and scaling of the application.\n\n## Technologies - Libraries\n\n- ✔️ **[`.NET 9`](https://github.com/dotnet/aspnetcore)** - .NET Framework and .NET Core, including ASP.NET and ASP.NET Core.\n- ✔️ **[`MVC Versioning API`](https://github.com/microsoft/aspnet-api-versioning)** - Set of libraries which add service API versioning to ASP.NET Web API, OData with ASP.NET Web API, and ASP.NET Core.\n- ✔️ **[`EF Core`](https://github.com/dotnet/efcore)** - Modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.\n- ✔️ **[`AspNetCore OpenApi`](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/openapi/aspnetcore-openapi?view=aspnetcore-9.0\u0026tabs=visual-studio#configure-openapi-document-generation)** - Provides built-in support for OpenAPI document generation in ASP.NET Core.\n- ✔️ **[`MediatR`](https://github.com/jbogard/MediatR)** - Simple, unambitious mediator implementation in .NET.\n- ✔️ **[`FluentValidation`](https://github.com/FluentValidation/FluentValidation)** - Popular .NET validation library for building strongly-typed validation rules.\n- ✔️ **[`Swagger \u0026 Swagger UI`](https://github.com/domaindrivendev/Swashbuckle.AspNetCore)** - Swagger tools for documenting API's built on ASP.NET Core.\n- ✔️ **[`Serilog`](https://github.com/serilog/serilog)** - Simple .NET logging with fully-structured events.\n- ✔️ **[`Scrutor`](https://github.com/khellang/Scrutor)** - Assembly scanning and decoration extensions for Microsoft.Extensions.DependencyInjection.\n- ✔️ **[`AutoMapper`](https://github.com/AutoMapper/AutoMapper)** - Convention-based object-object mapper in .NET.\n- ✔️ **[`NewId`](https://github.com/phatboyg/NewId)** - NewId can be used as an embedded unique ID generator that produces 128 bit (16 bytes) sequential IDs.\n- ✔️ **[`Sieve`](https://github.com/Biarity/Sieve)** - Sieve is a framework for .NET Core that adds sorting, filtering, and pagination functionality out of the box.\n- ✔️ **[`xUnit.net`](https://github.com/xunit/xunit)** - A free, open source, community-focused unit testing tool for the .NET Framework.\n- ✔️ **[`Respawn`](https://github.com/jbogard/Respawn)** - Respawn is a small utility to help in resetting test databases to a clean state.\n- ✔️ **[`Testcontainers`](https://github.com/testcontainers/testcontainers-dotnet)** - Testcontainers for .NET is a library to support tests with throwaway instances of Docker containers.\n- ✔️ **[`Bogus`](https://github.com/bchavez/Bogus)** - Bogus is a simple fake data generator for .NET.\n\n## Structure of Project\n\nIn this project I used [vertical slice architecture](https://jimmybogard.com/vertical-slice-architecture/) and [feature folder structure](http://www.kamilgrzybek.com/design/feature-folders/) to structure my files.\n\nTo `reduce coupling` in our code, we leverage `Mediatr` and `build pipelines` on top of it to handle `validation`, `logging`, and `transactions`. Our `domain` follows `Domain-Driven Design` principles and employs `value objects` for `business logic`. We also incorporate validation into our business processes. When we complete work within our domain, it raises a `domain event`. Depending on the requirements, we can then react to this event and take appropriate action to further our business goals.\n\nI `treat each request` as a `distinct` use case or `slice`, `encapsulating` and `grouping` `all concerns` from front-end to back with `vertical slice architecture`.\nIn traditional approach like `clean architecture`, When `adding` or `changing` a feature in an application in n-tire architecture, we are typically `touching many layers` in an application. We are changing the user interface, adding fields to models, modifying validation, and so on. Instead of `coupling across` a layer in traditional architecture, we `couple vertically along a slice`. We `minimize coupling` `between slices`, and `maximize coupling` `in a slice`.\n\nWith this approach, each of our `vertical slices` can `decide for itself` how to best fulfill the request. New features only add code, we're not changing shared code and worrying about side effects.\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"./assets/vertical-slice-architecture.png\" /\u003e\n\u003c/div\u003e\n\nIn traditional ASP.net controllers, related action methods are usually grouped in one controller. However, in my recent project, I opted to use the [REPR pattern](https://deviq.com/design-patterns/repr-design-pattern) (Route-Endpoint-Presenter-Resource) design pattern instead. With this pattern, each action is given its own small endpoint, consisting of a route, the action, and an `IMediator` instance (see [MediatR](https://github.com/jbogard/MediatR)), which is handled by a request-specific IRequestHandler to perform business logic before returning the result. This approach not only `separates` the action `logic` into `individual handlers`, but it also supports the `Single Responsibility`, `Open Close Principle` and `Don't Repeat Yourself` principles, resulting in `clean` and `thin controllers`.\n\nTo achieve better separation of concerns and cross-cutting concerns, I used the [Mediator pattern](https://dotnetcoretutorials.com/2019/04/30/the-mediator-pattern-in-net-core-part-1-whats-a-mediator/) in combination with `CQRS` (Command Query Responsibility Segregation) to `decompose features` into `small`, `vertical slices`. `Each slice` has a `group of classes specific to that feature`, including `command`, `handlers`, `infrastructure`, `repository`, and `controllers`. By grouping them together, we can easily maximize `performance`, `scalability`, and `simplicity`, as well as maintain and add features without creating breaking changes or side effects.\n\nWith `CQRS`, we can `reduce coupling` between layers and tune down specific methods to not follow general conventions. This is achieved by `cutting each business functionality into vertical slices`, where each command/query handler is a separate slice. As a result, each handler can be a `separate code unit`, even copy/pasted, allowing us to customize individual methods as needed. In contrast, in a `traditional layered` architecture, `changing the core generic mechanism` in `one layer` can `impact all methods`, which can be `time-consuming` and `challenging` to `maintain`.\n\nOverall, by using the `REPR` pattern and `CQRS` with the `Mediator` pattern, we can create a `better-structured` and more `maintainable` application, with improved `separation of concerns`.\n\n## Development Setup\n\n### Dotnet Tools Packages\nFor installing our requirement package with .NET cli tools, we need to install `dotnet tool manifest`.\n```bash\ndotnet new tool-manifest\n```\nAnd after that we can restore our dotnet tools packages with .NET cli tools from `.config` folder and `dotnet-tools.json` file.\n```\ndotnet tool restore\n```\n\n## How to Run\n\n### Docker Compose\n\nRun this app in docker using the [docker-compose.yml](./deployments/docker-compose/docker-compose.yml) file with the below command at the `root` of the application:\n\n```bash\ndocker-compose -f ./deployments/docker-compose/docker-compose.yml up -d\n```\n\n\u003e ### Documentation Apis\n\nEach microservice provides `API documentation` and navigate to `/swagger` for `Swagger OpenAPI` or `/scalar/v1` for `Scalar OpenAPI` to visit list of endpoints.\n\n# Support\n\nIf you like my work, feel free to:\n\n- ⭐ this repository. And we will be happy together :)\n\nThanks a bunch for supporting me!\n\n## Contribution\n\nThanks to all [contributors](https://github.com/meysamhadeli/ecommerce-monolith/graphs/contributors), you're awesome and this wouldn't be possible without you! The goal is to build a categorized, community-driven collection of very well-known resources.\n\nPlease follow this [contribution guideline](./CONTRIBUTION.md) to submit a pull request or create the issue.\n\n## License\nThis project is made available under the MIT license. See [LICENSE](https://github.com/meysamhadeli/ecommerce-monolith/blob/main/LICENSE) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeysamhadeli%2Fecommerce-monolith","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmeysamhadeli%2Fecommerce-monolith","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeysamhadeli%2Fecommerce-monolith/lists"}