Modern software applications continue to grow in complexity. As systems increase in size, maintaining clear boundaries between features, business rules, and technical components becomes challenging.
Traditional layered architectures often organize applications by technical concerns such as controllers, services, repositories, and database access. While this approach works for many projects, large applications may become difficult to understand because related functionality is spread across multiple layers.
What is Vertical Slice Architecture?
Vertical Slice Architecture is a software design pattern where an application is divided into independent feature slices. Each slice represents a specific business capability and contains everything required to complete that feature.
Instead of organizing code by technical responsibility, the application is organized by user actions and business scenarios.
Example Feature-Based Thinking
Why Traditional Layered Architecture Can Become Complex
Many ASP.NET Core applications begin with a simple layered structure:
- Controllers
- Business Services
- Repositories
- Data Access Layer
- Models
As the application grows, developers may face challenges such as:
- Business logic spread across multiple locations
- Difficulty finding code related to a feature
- Large service classes
- Frequent changes affecting unrelated areas
- Complex dependency relationships
Core Idea Behind Vertical Slice Architecture
The main idea is simple: organize code around what the application does rather than how the application is technically built.
Each feature becomes an independent slice that contains its own workflow.
Example Business Features
- Register User
- Create Order
- Process Payment
- Generate Invoice
- Update Customer Profile
Feature-Based Organization
In Vertical Slice Architecture, folders represent business features instead of technical layers.
Example Project Structure
Each feature contains everything required for that business operation.
Vertical Slice Architecture Principles
- Organize code by business features
- Keep features independent
- Minimize unnecessary sharing
- Use simple and focused workflows
- Separate business behavior from infrastructure concerns
Vertical Slice Architecture vs Layered Architecture
| Layered Architecture | Vertical Slice Architecture |
|---|---|
| Organized by technical layers | Organized by business features |
| Controllers grouped together | Features grouped together |
| Shared services are common | Feature-specific logic is preferred |
| Changes may affect multiple layers | Changes usually stay inside one slice |
Vertical Slice Architecture vs Clean Architecture
Vertical Slice Architecture and Clean Architecture solve different problems but can be combined together.
Clean Architecture focuses on dependency direction, while Vertical Slice Architecture focuses on organizing application functionality around features.
CQRS in Vertical Slice Architecture
Command Query Responsibility Segregation (CQRS) is a commonly used pattern with Vertical Slice Architecture. CQRS separates operations that modify data from operations that retrieve data.
Instead of creating large service classes containing multiple responsibilities, each operation becomes a separate request with its own handler.
CQRS Concept
Command -> Changes Application State -> Database Update
Query -> Reads Application Data -> Returns Result
Commands and Queries
Commands
Commands represent actions that change application data.
Examples:
- Create Customer
- Update Order
- Delete Product
- Process Payment
Queries
Queries are used only for retrieving information and should not modify system state.
Examples:
- Get Customer Details
- Search Products
- Get Order History
MediatR Integration with ASP.NET Core
MediatR is a popular library used to implement the mediator pattern in .NET applications. It allows requests and handlers to communicate without creating direct dependencies.
Installing MediatR Package
dotnet add package MediatR
Registering MediatR in ASP.NET Core
builder.Services
.AddMediatR(configuration =>
{
configuration.RegisterServicesFromAssembly(typeof(Program).Assembly);
});
After registration, ASP.NET Core can automatically locate and execute request handlers.
Create Order Feature Example
A typical Vertical Slice feature contains the request model, handler, validation, and response model together.
Feature Structure
Creating a Command
public record CreateOrderCommand(string CustomerName,decimal Amount):IRequest<int>;
The command represents the action of creating a new order.
Creating Command Handler
public class CreateOrderHandler:IRequestHandler<CreateOrderCommand,int>
{
private readonly AppDbContext _context;
public CreateOrderHandler(AppDbContext context)
{
_context = context;
}
public async Task<int> Handle(CreateOrderCommand request,CancellationToken cancellationToken)
{
var order = new Order
{
CustomerName = request.CustomerName,
Amount = request.Amount
};
_context.Orders.Add(order);
await _context.SaveChangesAsync(cancellationToken);
return order.Id;
}
}
Creating Query Feature
Queries are separated from commands because their responsibilities are different.
Get Orders Query Example
public record GetOrdersQuery:IRequest<List<OrderDto>>;
Query Handler Example
public class GetOrdersHandler:IRequestHandler<GetOrdersQuery,List<OrderDto>>
{
private readonly AppDbContext _context;
public GetOrdersHandler(AppDbContext context)
{
_context = context;
}
public async Task<List<OrderDto>> Handle(GetOrdersQuery request,CancellationToken cancellationToken)
{
return await _context.Orders.Select(order => new OrderDto
{
Id = order.Id,
CustomerName = order.CustomerName,
Amount = order.Amount
}).ToListAsync(cancellationToken);
}
}
API Endpoint with Vertical Slice Architecture
Endpoints should remain simple. Their responsibility is receiving requests and sending them to the correct feature handler.
Controller Example
[ApiController]
[Route("api/orders")]
public class OrdersController : ControllerBase
{
private readonly IMediator _mediator;
public OrdersController(IMediator mediator)
{
_mediator = mediator;
}
[HttpPost]
public async Task<IActionResult>Create(CreateOrderCommand command)
{
var id = await _mediator.Send(command);
return Ok(id);
}
}
Minimal API with Vertical Slice Architecture
Vertical Slice Architecture works especially well with ASP.NET Core Minimal APIs because endpoints can directly represent features.
app.MapPost("/orders", async (CreateOrderCommand command, IMediator mediator) =>
{
var result = await mediator.Send(command);
return Results.Ok(result);
});
Validation with FluentValidation
Each feature can contain its own validation rules instead of placing validation logic in shared locations.
Installing FluentValidation
dotnet add package FluentValidation
Validator Example
public class CreateOrderValidator : AbstractValidator<CreateOrderCommand>
{
public CreateOrderValidator()
{
RuleFor(x => x.CustomerName).NotEmpty();
RuleFor(x => x.Amount).GreaterThan(0);
}
}
Entity Framework Core Integration
Entity Framework Core can be used directly inside feature handlers when the feature requires database access.
This avoids unnecessary abstraction layers and keeps related logic together.
DbContext Example
public class AppDbContext: DbContext
{
public DbSet<Order> Orders { get; set; }
public AppDbContext(DbContextOptions options): base(options)
{
}
}
Dependency Injection Configuration
Dependency Injection is still an important part of Vertical Slice Architecture. However, dependencies are usually registered based on application requirements rather than creating large shared service layers.
Registering Application Services
builder.Services.AddDbContext<AppDbContext>(options =>
{
options.UseSqlServer(connectionString);
});
builder.Services.AddMediatR(configuration =>
{
configuration.RegisterServicesFromAssembly(typeof(Program).Assembly);
});
The application remains loosely coupled while allowing each feature to control its own workflow.
Advanced Feature Organization
For large applications, each feature can contain all files required to complete a business operation.
Keeping Features Independent
A key principle of Vertical Slice Architecture is minimizing unnecessary communication between features.
A feature should own its business rules and expose only what other parts of the application actually need.
Example
The Order feature should not directly depend on internal implementation details of the Customer feature.
Testing Vertical Slices
One of the biggest advantages of Vertical Slice Architecture is improved testability. Each feature can be tested independently.
Testing focuses on user behavior rather than internal technical layers.
Unit Testing Feature Handlers
Handlers are small and focused, making them easier to test.
Example Handler Test
[Fact]
public async Task CreateOrder_Should_Return_OrderId()
{
var command = new CreateOrderCommand("John Smith",100);
var result = await handler.Handle(command, CancellationToken.None);
Assert.True(result > 0);
}
Integration Testing Vertical Slices
Integration tests verify that complete features work correctly with real dependencies such as databases and APIs.
Integration Test Flow
HTTP Request -> Feature Endpoint -> Command / Query Handler -> Database -> Response
Benefits of Feature-Based Testing
- Tests are easier to locate
- Business scenarios are clearly represented
- Failures are easier to diagnose
- Features can evolve independently
- Less dependency mocking is required
Handling Cross-Cutting Concerns
Applications usually contain common concerns such as logging, authorization, validation, and exception handling.
Vertical Slice Architecture handles these concerns using pipeline behaviors or middleware.
MediatR Pipeline Behavior Example
public class LoggingBehavior<TRequest,TResponse> : IPipelineBehavior<TRequest,TResponse>
{
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
{
Console.WriteLine("Request Started");
var response = await next();
Console.WriteLine("Request Completed");
return response;
}
}
Authorization in Vertical Slices
Authorization rules can be placed close to the feature that requires them.
Example
public class DeleteOrderCommand : IRequest<bool>
{
public int OrderId { get; set; }
}
The handler can verify whether the current user has permission before performing the operation.
Error Handling Strategy
Each feature should return meaningful responses while common exception handling can be centralized.
Example Response Model
public record Result<T> (bool Success, T Data, string Message);
Scaling Large ASP.NET Core Applications
Vertical Slice Architecture works well for large applications because teams can work on separate features without constantly modifying shared code.
Team Development Benefits
- Teams can own specific business areas
- Features can be deployed independently
- Code ownership becomes clearer
- Merge conflicts are reduced
- New developers understand the system faster
Vertical Slice Architecture with Microservices
Vertical Slice Architecture can also complement microservice-based systems.
A microservice can contain multiple vertical slices representing different business capabilities.
When Should You Use Vertical Slice Architecture?
Vertical Slice Architecture is a good choice when applications have:
- Many business workflows
- Frequent feature changes
- Large development teams
- Complex domain requirements
- Long-term maintenance needs
When It May Not Be Required
Small applications with simple CRUD operations may not need a full Vertical Slice approach.
For smaller projects, a simple MVC or traditional layered structure may be easier to maintain.
Vertical Slice Architecture Best Practices
Following recommended practices helps teams build clean, maintainable, and scalable applications using Vertical Slice Architecture.
1. Design Features Around Business Actions
A feature should represent a meaningful business operation instead of a technical operation.
Good examples:
- Approve Loan Application
- Submit Order
- Generate Customer Report
- Process Payment
Avoid creating features only around database operations such as "InsertCustomer" or "UpdateRecord".
2. Keep Handlers Small and Focused
Each handler should perform one specific business task. Large handlers usually indicate that a feature contains too many responsibilities.
3. Avoid Creating Unnecessary Shared Code
Developers often create common utilities too early. Shared code should only be introduced when there is a real business requirement.
Excessive sharing can create strong dependencies between unrelated features.
4. Keep Business Logic Close to the Feature
Validation rules, request models, and workflows should remain close to the feature that uses them.
Common Vertical Slice Architecture Mistakes
- Creating large shared service classes
- Mixing multiple business operations inside one handler
- Creating unnecessary abstractions
- Sharing database logic between unrelated features
- Ignoring testing requirements
- Using Vertical Slice only as folder organization without changing design
Enterprise Vertical Slice Architecture Example
A large business application may contain hundreds of independent features. Each feature represents a business capability.
Vertical Slice Architecture with Clean Architecture
Many enterprise systems combine both approaches to get the benefits of each pattern.
- Vertical slices organize business features
- Clean Architecture manages dependency rules
- CQRS separates commands and queries
- Infrastructure remains replaceable
Advantages of Vertical Slice Architecture
- Better code organization
- Feature-focused development
- Easier maintenance
- Reduced coupling
- Improved developer productivity
- Better testing experience
- Supports large development teams
- Easier application evolution
Frequently Asked Questions
Is Vertical Slice Architecture a replacement for Clean Architecture?
No. Vertical Slice Architecture focuses on organizing application features, while Clean Architecture focuses on dependency management. They can be used together.
Does Vertical Slice Architecture require CQRS?
No. CQRS is commonly used with Vertical Slice Architecture, but it is not mandatory. Teams can adopt feature-based organization without implementing CQRS.
Is Vertical Slice Architecture suitable for ASP.NET Core applications?
Yes. ASP.NET Core provides excellent support through Minimal APIs, dependency injection, Entity Framework Core, and libraries such as MediatR.
Is Vertical Slice Architecture good for enterprise applications?
Yes. It is especially useful for applications with many business workflows, multiple development teams, and frequent feature changes.
Does Vertical Slice Architecture increase code duplication?
Some duplication may occur because features are intentionally isolated. However, this often improves maintainability by avoiding tightly coupled shared components.
Conclusion
Vertical Slice Architecture provides a modern approach to designing ASP.NET Core applications by organizing software around business features instead of technical layers.
By combining feature-based organization, CQRS, MediatR, Entity Framework Core, and focused testing strategies, development teams can create applications that are easier to understand, maintain, and scale.
For complex enterprise systems, Vertical Slice Architecture provides a flexible foundation that supports continuous development and long-term growth.