Vertical Slice Architecture in .NET Core

Vertical Slice Architecture is an architectural pattern where the application is organized by feature (business capability) instead of technical layers such as Controllers, Services, and Repositories.

Each feature contains everything it needs:

  • API Endpoint
  • Request
  • Validation
  • Business Logic
  • Data Access
  • Response

Instead of navigating across multiple folders, everything related to a feature stays together.

Traditional Layered Architecture

API
│
├── Controllers
│      EmployeeController.cs
│
├── Services
│      EmployeeService.cs
│
├── Repositories
│      EmployeeRepository.cs
│
├── DTOs
│
├── Models
│
└── Data

Vertical Slice Architecture

Application
│
├── Employees
│     ├── CreateEmployee
│     │      Command.cs
│     │      Validator.cs
│     │      Handler.cs
│     │      Endpoint.cs
│     │      Response.cs
│     │
│     ├── GetEmployee
│     │      Query.cs
│     │      Handler.cs
│     │      Endpoint.cs
│     │
│     └── DeleteEmployee
│
├── Departments
│
├── Attendance
│
└── Payroll

Advantages

✅ Feature-based organization
✅ Easier to navigate
✅ Better scalability for large applications
✅ Less coupling between features
✅ Smaller classes
✅ Simpler testing of individual handlers
✅ Fits naturally with CQRS
✅ Works well with Minimal APIs
✅ Reduces boilerplate (no unnecessary service/repository layers)

Disadvantages

❌ Can lead to duplicated helper code if common functionality isn’t extracted thoughtfully.
❌ Requires discipline to keep shared logic in appropriate cross-cutting components. ❌ New developers familiar only with layered architecture may need time to adjust. ❌ Large features can still become complex if not broken into smaller slices.


When to Use Vertical Slice Architecture

This architecture is a great fit for:

  • Medium to large .NET applications
  • Microservices
  • REST APIs
  • CQRS-based systems
  • Clean Architecture implementations
  • Modular monoliths

It may be unnecessary for very small CRUD applications with only a handful of endpoints.


Vertical Slice vs Layered Architecture

AspectLayered ArchitectureVertical Slice Architecture
OrganizationBy technical layerBy feature
NavigationAcross multiple foldersInside one feature folder
Business LogicService layerHandler
Data AccessRepositoryDbContext (typically)
APIControllersMinimal APIs or thin controllers
TestingServices + controllersIndividual handlers
ScalabilityCan become harder to navigateEasier to scale by feature
CQRS SupportOptionalExcellent

Why Vertical Slice Fits Microservices

Traditional LayeredVertical Slice
Shared services become large over timeEach use case is isolated
Changes span multiple layersMost changes stay within one feature folder
High coupling between layersHigh cohesion within each slice
Controllers become thin, services become “God classes”Handlers remain focused on a single responsibility
Harder to onboard new developersEasier to locate feature-related code
Repositories often add boilerplateEF Core DbContext is commonly injected directly

Best Practices for Vertical Slice in Microservices

  1. One microservice = one bounded context.
  2. One vertical slice = one business use case.
  3. Keep each handler focused on a single responsibility.
  4. Use CQRS to separate commands and queries.
  5. Use Entity Framework Core directly unless a repository abstraction is truly needed.
  6. Publish integration events (e.g., via Kafka or RabbitMQ) rather than making synchronous service-to-service calls where asynchronous communication is appropriate.
  7. Use the Outbox Pattern for reliable event publishing.
  8. Keep shared infrastructure (logging, authentication, caching, telemetry) outside feature folders.
  9. Keep domain rules in the domain model when they represent business invariants.
  10. Ensure each microservice owns its own database to maintain loose coupling.

Key Takeaway

In a microservices ecosystem:

  • Microservice defines the business boundary (e.g., Student, Course, Payment).
  • Vertical Slice defines a single business use case within that boundary (e.g., Create Student, Search Student, Refund Payment).

This combination provides strong modularity, aligns well with CQRS and event-driven design, and makes each service easier to develop, test, and evolve independently.

Share Button

Leave a Reply

Your email address will not be published. Required fields are marked *