This is a simple example project demonstrating the usage of Vertical Slice Architecture in .NET 7, along with MediatR, Carter, FluentValidation, MediatR pipelines for validation and logging, middlewares for global exception handling and validation responses, the CQRS pattern, Entity Framework for commands, and Dapper for queries, and SQLite as database provider.
Vertical Slice Architecture is an architectural pattern that emphasizes organizing your code around features or slices of your application, rather than traditional layered architectures. It helps maintain a clean and focused structure for each feature while keeping your codebase more maintainable and scalable.
In this example, we will build a simple "run tracker" for managing activities and workouts, using the CQRS pattern for separation of concerns. Entity Framework will be used for handling commands (write operations), Dapper will be used for queries (read operations) and SQLite will be used to store our data locally.
- .NET 7
- MediatR: For implementing the Mediator pattern.
- Carter: For mapping our Minimal APIs.
- FluentValidation: For request validation.
- Entity Framework Core: For handling command operations (Create, Update, Delete).
- Dapper: For handling query operations (Read).
-
Clone this repository:
https://github.com/giorgioverzicco/dotnet-vertical-slice-simple-example.git
-
Navigate to the project folder:
cd dotnet-vertical-slice-simple-example
-
Build and run the application:
dotnet run
-
Access the API using your preferred HTTP client (e.g., Postman, cURL, or a web browser) at
http://localhost:5000
orhttps://localhost:5001
.
The project structure follows the Vertical Slice Architecture, where each feature or slice of the application is organized in a self-contained folder or file.
- Endpoint:
/activities
- Description: Create a new activity.
- Request:
POST
with a JSON body containing the entity data. - Validation: Request validation is handled using FluentValidation.
- Command Handling: Uses Entity Framework Core to create the entity.
- Logging: Log request and response using Microsoft Logger.
- Request Example:
{
"userId": 1,
"activityType": "run",
"distanceInMeters": 1000.0,
"duration": "00:45:00",
"date": "2023-11-09",
"location": "Central Park",
"notes": "Morning jog in the park"
}
- Endpoint:
/activities/{activityId:int}
- Description: Get an activity by ID.
- Request:
GET
with the entity ID as a route parameter. - Validation: Request validation is handled using FluentValidation.
- Query Handling: Uses Dapper to fetch the entity by ID.
- Logging: Log request and response using Microsoft Logger.
- Endpoint:
/workouts
- Description: Create a new workout.
- Request:
POST
with a JSON body containing the entity data. - Validation: Request validation is handled using FluentValidation.
- Command Handling: Uses Entity Framework Core to create the entity.
- Logging: Log request and response using Microsoft Logger.
- Request Example:
{
"userId": 1,
"activityIds": [1],
"startTime": "2023-11-15T07:00:00Z",
"endTime": "2023-11-15T08:00:00Z",
"notes": "Morning marathon training"
}
- Endpoint:
/workouts/{workoutId:int}
- Description: Get a workout by ID.
- Request:
GET
with the entity ID as a route parameter. - Validation: Request validation is handled using FluentValidation.
- Query Handling: Uses Dapper to fetch the entity by ID.
- Logging: Log request and response using Microsoft Logger.
- Handles request validation using FluentValidation.
- Returns appropriate validation responses for invalid requests.
- Catches unhandled exceptions and returns a structured error response.
- Uses Microsoft Logger for structured logging.
- Logs request and response information for each API endpoint.
- Configuration settings are stored in
appsettings.json
. - Update the database connection string and other settings as needed.
This example demonstrates a simple application following the Vertical Slice Architecture, do not assume that the code written in this repository is in any shape or form production ready.
You can use this as a starting point to build more complex applications while maintaining a clean and organized codebase.
Feel free to explore and expand upon this project to suit your specific requirements.