Vertical Slice Architecture gives you incredible speed and flexibility by organizing code around features instead of technical layers.
Each slice encapsulates all aspects of a specific feature, including the API, business logic, and data access.
When you implement each feature, the necessary code stays together in the same folder or file.
Many developers were adopting Vertical Slice Architecture because of the following benefits:
- Changes are isolated to specific features, reducing the risk of unintended side effects.
- Other developers and teams to work on different features independently.
- You can use different technologies or approaches within each slice as needed (aka CQRS on steroids).
- It's easier to navigate in the solution, as all the code for a specific feature stays together.
I have built many projects using N-Layered and Clean Architecture, and one of the biggest challenges I faced was too much abstraction.
These types of Architectures often result in you creating a lot of premature abstractions that tend to solve some future problems:
- What if a database might change in the future
- What if we need to replace a messaging or logging library
- What if this, what if that...
That's why I liked the Vertical Slice Architecture approach from the start.
I finally have the freedom to get rid of many premature abstractions and have the actual implementation sit in my slices.
But this freedom comes with a challenge: you can end up with a lot of code duplication:
- Two slices need similar validation logic.
- Three features query the same database table.
- Five handlers format dates the same way.
That's why some devs critique Vertical Slice Architecture, saying it violates the DRY principle and encourages the WET Principle (write everything twice).
I have built a few projects with Vertical Slice Architecture in the last few years, and I want to show you my pragmatic approach to managing duplication.
In this post, we will explore:
- Why Vertical Slice Architecture Leads to Code Duplication
- Detecting Code Duplication
- How to Avoid Duplication in Database Concerns
- How to Avoid Duplication in Infrastructure Concerns
- How to Avoid Duplication in Business Concerns
- How to Avoid Duplication in Application Concerns
- Decision Framework When Addressing Code Duplication
Let's dive in.
Why Vertical Slice Architecture Leads to Code Duplication
In traditional layered architecture, you organize code by technical concerns: Controllers, Services, Repositories, and Models.
When you need to add a new feature, you touch multiple layers. You add a controller method, a service method, a repository method, and maybe a DTO.
This structure naturally pushes you toward reuse.
If two features need similar logic, you put it in a shared service.
If three features query the same table, you add a method to the repository.
Vertical Slice Architecture flips this approach.
Each feature is a vertical slice that contains everything it needs: the endpoint, the handler, the validation, the data access, and the response model.
Here is what a typical VSA project structure looks like:
Each slice is independent. CreateShipment feature does not call GetShipmentByNumber and doesn't share code with other features.
This independence is the superpower of VSA. You can change one feature without worrying about breaking another.
But this independence also makes duplication visible.
If CreateShipment and ProcessShipment both need to validate that a product exists, you will write that validation twice.
But before addressing every code duplication case, you need to stop and think for a while.
Two pieces of code can look identical today and evolve in completely different directions tomorrow.
If you share them too early, you create coupling.
When one feature needs to change, you have to modify shared code that affects the other feature.
This is the cost of premature abstraction: you trade the flexibility to change one feature independently for the illusion of DRY code.
And the most important part is that most developers misunderstand DRY.
They think it's about removing duplicate code. It's not.
DRY is about duplicated knowledge, not the code.
Duplicate code is only a symptom. The real problem is duplicated business rules hiding across the system.
Here is where most teams get it wrong:
- ❌ They extract shared helpers too early.
- ❌ They create generic utilities that are hard to maintain
- ❌ They couple unrelated features just to reduce duplication.
This actually makes the code worse. Sometimes duplication is fine.
If two pieces of code change for different reasons, keep them separate.
This follows Single Responsibility better than forced reuse.
DRY is violated only when the same reason to change exists in multiple places.
Okay, enough theory.
Now, let's explore how we can avoid duplication and when and where we should extract shared code.
👉 Read the full article on my newsletter: https://antondevtips.com/blog/how-to-avoid-code-duplication-in-vertical-slice-architecture-in-dotnet
Top comments (0)