Modular Monolith with DDD
Full Modular Monolith .NET application with Domain-Driven Design approach.
Announcement
Learn, use and benefit from this project only if:
- You condemn Russia and its military aggression against Ukraine
- You recognize that Russia is an occupant that unlawfully invaded a sovereign state
- You support Ukraine's territorial integrity, including its claims over temporarily occupied territories of Crimea and Donbas
- You reject false narratives perpetuated by Russian state propaganda
Otherwise, leave this project immediately and educate yourself.
Putin, idi nachuj.
CI
FrontEnd application
FrontEnd application : Modular Monolith With DDD: FrontEnd React application
Table of contents
1.1 Purpose of this Repository
3.3 API and Module Communication
3.4 Module Requests Processing via CQRS
3.5 Domain Model Principles and Attributes
3.11 Architecture Decision Log
3.14 System Integration Testing
3.16 Database change management
10. Inspirations and Recommendations
1. Introduction
1.1 Purpose of this Repository
This is a list of the main goals of this repository:
- Showing how you can implement a monolith application in a modular way
- Presentation of the full implementation of an application
- This is not another simple application
- This is not another proof of concept (PoC)
- The goal is to present the implementation of an application that would be ready to run in production
- Showing the application of best practices and object-oriented programming principles
- Presentation of the use of design patterns. When, how and why they can be used
- Presentation of some architectural considerations, decisions, approaches
- Presentation of the implementation using Domain-Driven Design approach (tactical patterns)
- Presentation of the implementation of Unit Tests for Domain Model (Testable Design in mind)
- Presentation of the implementation of Integration Tests
- Presentation of the implementation of Event Sourcing
- Presentation of C4 Model
- Presentation of diagram as text approach
1.2 Out of Scope
This is a list of subjects which are out of scope for this repository:
- Business requirements gathering and analysis
- System analysis
- Domain exploration
- Domain distillation
- Domain-Driven Design strategic patterns
- Architecture evaluation, quality attributes analysis
- Integration, system tests
- Project management
- Infrastructure
- Containerization
- Software engineering process
- Deployment process
- Maintenance
- Documentation
1.3 Reason
The reason for creating this repository is the lack of something similar. Most sample applications on GitHub have at least one of the following issues:
- Very, very simple - few entities and use cases implemented
- Not finished (for example there is no authentication, logging, etc..)
- Poorly designed (in my opinion)
- Poorly implemented (in my opinion)
- Not well described
- Assumptions and decisions are not clearly explained
- Implements "Orders" domain - yes, everyone knows this domain, but something different is needed
- Implemented in old technology
- Not maintained
To sum up, there are some very good examples, but there are far too few of them. This repository has the task of filling this gap at some level.
1.4 Disclaimer
Software architecture should always be created to resolve specific business problems. Software architecture always supports some quality attributes and at the same time does not support others. A lot of other factors influence your software architecture - your team, opinions, preferences, experiences, technical constraints, time, budget, etc.
Always functional requirements, quality attributes, technical constraints and other factors should be considered before an architectural decision is made.
Because of the above, the architecture and implementation presented in this repository is one of the many ways to solve some problems. Take from this repository as much as you want, use it as you like but remember to always pick the best solution which is appropriate to the problem class you have.
1.5 Give a Star
My primary focus in this project is on quality. Creating a good quality product involves a lot of analysis, research and work. It takes a lot of time. If you like this project, learned something or you are using it in your applications, please give it a star :star:. This is the best motivation for me to continue this work. Thanks!
1.6 Share It
There are very few really good examples of this type of application. If you think this repository makes a difference and is worth it, please share it with your friends and on social networks. I will be extremely grateful.
2. Domain
2.1 Description
Definition:
Domain - A sphere of knowledge, influence, or activity. The subject area to which the user applies a program is the domain of the software. Domain-Driven Design Reference, Eric Evans
The Meeting Groups domain was selected for the purposes of this project based on the Meetup.com system.
Main reasons for selecting this domain:
- It is common, a lot of people use the Meetup site to organize or attend meetings
- There is a system for it, so everyone can check this implementation against a working site which supports this domain
- It is not complex so it is easy to understand
- It is not trivial - there are some business rules and logic and it is not just CRUD operations
- You don't need much specific domain knowledge unlike other domains like financing, banking, medical
- It is not big so it is easier to implement
Meetings
The main business entities are Member
, Meeting Group
and Meeting
. A Member
can create a Meeting Group
, be part of a Meeting Group
or can attend a Meeting
.
A Meeting Group Member
can be an Organizer
of this group or a normal Member
.
Only an Organizer
of a Meeting Group
can create a new Meeting
.
A Meeting
has attendees, not attendees (Members
which declare they will not attend the Meeting
) and Members
on the Waitlist
.
A Meeting
can have an attendee limit. If the limit is reached, Members
can only sign up to the Waitlist
.
A Meeting Attendee
can bring guests to the Meeting
. The number of guests allowed is an attribute of the Meeting
. Bringing guests can be unallowed.
A Meeting Attendee
can have one of two roles: Attendee
or Host
. A Meeting
must have at least one Host
. The Host
is a special role which grants permission to edit Meeting
information or change the attendees list.
A Member
can comment Meetings
. A Member
can reply to, like other Comments
. Organizer
manages commenting of Meeting
by Meeting Commenting Configuration
. Organizer
can delete any Comment
.
Each Meeting Group
must have an organizer with active Subscription
. One organizer can cover 3 Meeting Groups
by his Subscription
.
Additionally, Meeting organizer can set an Event Fee
. Each Meeting Attendee
is obliged to pay the fee. All guests should be paid by Meeting Attendee
too.
Administration
To create a new Meeting Group
, a Member
needs to propose the group. A Meeting Group Proposal
is sent to Administrators
. An Administrator
can accept or reject a Meeting Group Proposal
. If a Meeting Group Proposal
is accepted, a Meeting Group
is created.
Payments
Each Member
who is the Payer
can buy the Subscription
. He needs to pay the Subscription Payment
. Subscription
can expire so Subscription Renewal
is required (by Subscription Renewal Payment
payment to keep Subscription
active).
When the Meeting
fee is required, the Payer
needs to pay Meeting Fee
(through Meeting Fee Payment
).
Users
Each Administrator
, Member
and Payer
is a User
. To be a User
, User Registration
is required and confirmed.
Each User
is assigned one or more User Role
.
Each User Role
has set of Permissions
. A Permission
defines whether User
can invoke a particular action.
2.2 Conceptual Model
Definition:
Conceptual Model - A conceptual model is a representation of a system, made of the composition of concepts that are used to help people know, understand, or simulate a subject the model represents. Wikipedia - Conceptual model
Conceptual Model
PlantUML version:
VisualParadigm version (not maintained, only for demonstration):
Conceptual Model of commenting feature
2.3 Event Storming
While a Conceptual Model focuses on structures and relationships between them, behavior and events that occur in our domain are more important.
There are many ways to show behavior and events. One of them is a light technique called Event Storming which is becoming more popular. Below are presented 3 main business processes using this technique: user registration, meeting group creation and meeting organization.
Note: Event Storming is a light, live workshop. One of the possible outputs of this workshop is presented here. Even if you are not doing Event Storming workshops, this type of process presentation can be very valuable to you and your stakeholders.
User Registration process
Meeting Group creation
Meeting organization
Payments Download high resolution file
3. Architecture
3.0 C4 Model
C4 model is a lean graphical notation technique for modelling the architecture of software systems.
As can be found on the website of the author of this model (Simon Brown): The C4 model was created as a way to help software development teams describe and communicate software architecture, both during up-front design sessions and when retrospectively documenting an existing codebase
Model C4 defines 4 levels (views) of the system architecture: System Context, Container, Component and Code. Below are examples of each of these levels that describe the architecture of this system.
Note: The PlantUML (diagram as text) component was used to describe all C4 model levels. Additionally, for levels C1-C3, a C4-PlantUML plug-in connecting PlantUML with the C4 model was used.