When we’re building applications, we generally find patterns as we’re progressing. Whether it’s within the current app you’re building or when you move on to the next app, you carry your learnings for what worked well and what didn’t. We leverage design patterns and architectures we like and perhaps discard ones that didn’t serve us well. So when it comes to building solutions leveraging vertical slices, I have an ASP.NET Core vertical slice project template that I love to use.
In this article, I’ll detail why I made the vertical slice project template that I have, what it is, and how it works, as well as different ways to use it. There’s code included in the article as well as a full GitHub solution that you can clone down. Let’s jump into it!
Why Have a Vertical Slice Project Template? What’s All The Hype?
Lately, the buzz around vertical slices and vertical slice architecture has been growing, and it’s not without reason. This architectural paradigm is not only something I hold in high regard but also a methodology I find incredibly effective for iterative software delivery. The vertical slice approach has been gaining traction, possibly riding the wave of trendy tech topics, yet the conversations around it are valuable and eye-opening.
If you’re not already on board with this, I’d recommend delving into some reading about vertical slices. You might also want to explore the architectural essence of vertical slices before venturing further. Much of my earlier content on plugins dovetails nicely with the vertical slice discourse we’ll be plunging into. So, if you find either of these intriguing, it could be rewarding to explore the other side and see how they intermingle seamlessly.
While it could be a fleeting trend of the moment, the rise in discussions around this topic is still exciting for me. The tech community is vast with varied architectural philosophies and strategies for iterative changes. The ongoing dialogues around these differing perspectives are not only enriching but also a vital part of our collective learning journey!
This vertical slice project template is my response to some of the community asking for more. While I can continue to cover the architectural side of vertical slices as well as how to use vertical slices as a development paradigm, this felt necessary. This template, in spirit, is what I use when kicking off new projects.
Unfolding the Project Layout of the Vertical Slice Project Template
Before delving into the details, I’d like to point you toward a video walkthrough of the project template that I’ve created. If you are a newsletter subscriber, you unlocked an exclusive article on this vertical slice project template as well as early access to this YouTube video:
Now, the vertical slice project template in focus is nestled within my Dev Leader GitHub repository, ready to be cloned. It unfurls a solution featuring a solitary project for an ASP.NET Core web API at the moment. The beauty here is, once you have it in your local setup, a press of the play button in Visual Studio sets it into motion!
Within this setup, our main entry point is defined using top-level statements. It takes the reins for high-level dependency injection initialization, courtesy of Autofac. A closely associated Autofac module orchestrates the initialization of the web application in a manner that leaves the door open for registering other routes down the line. This is where the essence of the vertical slice comes into play, housed within the Features folder.
Within the Features folder, you’ll find individual folders, each of which represents our vertical slices. I’ve thrown in two for your perusal, albeit only one is accompanied by an associated Autofac module. This module showcases a glimpse of how a vertical slice implementation could take charge of route registration. If you’re itching to delve deeper, either hit play on the video or continue traversing through the code narrative laid out here!
This part of the vertical slice project template isn’t just about displaying the structure but painting a vivid picture of how the vertical slices are orchestrated in this setup. As you meander through the code, the concept of vertical slices in project architecture starts morphing from abstract to concrete.
Unfurling the Vertical Slice Project Template Code
The essence of this vertical slice project template unfolds as you dive into the core of the code. It begins at the entry point, where top-level statements make an appearance, eliminating the need for an explicit Program class or Main() method. Honestly, isn’t that such an awesome feature for readability?
Here’s how it looks:
using System.Reflection;
using Autofac;
ContainerBuilder containerBuilder = new();
containerBuilder.RegisterAssemblyModules(
Assembly.GetExecutingAssembly());
using var container = containerBuilder.Build();
using var scope = container.BeginLifetimeScope();
var app = scope.Resolve<ConfiguredWebApplication>();
app.WebApplication.Run();
In this snippet, we create our Autofac container builder, registering all desired modules. For this template, the currently running assembly suffices. However, you’re not just limited to this assembly—perhaps you’ve segregated your vertical slices or plugins—you can tweak this segment accordingly. If you need to scan a folder for assemblies to load, this article should help.
Now, let’s head over to the Autofac module tailored for the core application, which lays down the groundwork for our web application, prepping it for its eventual launch:
using Autofac;
internal sealed class WebApplicationModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder
.Register(ctx => WebApplication
.CreateBuilder(Environment.GetCommandLineArgs()))
.SingleInstance();
builder
.Register(ctx =>
{
var webApplicationBuilder = ctx.Resolve<WebApplicationBuilder>();
var webApplication = webApplicationBuilder.Build();
return webApplication;
})
.SingleInstance();
builder
.Register(ctx =>
{
ctx.Resolve<IEnumerable<RouteRegistrationDependencyMarker>>();
var webApplication = ctx.Resolve<WebApplication>();
webApplication.UseHttpsRedirection();
ConfiguredWebApplication configuredWebApplication = new(webApplication);
return configuredWebApplication;
})
.SingleInstance();
}
}
public sealed record RouteRegistrationDependencyMarker { }
internal sealed record ConfiguredWebApplication(
WebApplication WebApplication);
I’ve explained the mechanics in the accompanying video, but let’s dive deeper here too. This structure unrolls a pathway, letting you add in configurations before the web application hums to life. There’s some interesting code in the final registration, where a marker type named RouteRegistrationDependencyMarker
gets resolved, orchestrating other registrations to step in and execute. This choreography allows the vertical slice project template to register routes before the web application takes its first breath, orchestrating it through this marker interface to control the resolution order. Likewise, a marker interface named ConfiguredWebApplication
signals when the setup is complete, readying the stage for the run.
Let’s now check out one of the vertical slice module examples nestled in the template project:
using Autofac;
namespace AspVerticalSliceTemplate.App.Features.Feature1;
internal sealed class Feature1Module : Module
{
protected override void Load(ContainerBuilder builder)
{
builder
.Register(ctx =>
{
var app = ctx.Resolve<WebApplication>();
app.MapGet("hello", () => "Hello World!");
return new RouteRegistrationDependencyMarker();
})
.SingleInstance();
}
}
Here, it resolves the web application instance, gaining full autonomy to register the routes that it wants. By returning the marker type RouteRegistrationDependencyMarker
, this registration will get run by Autofac when the previous code we were looking at asks to resolve all of these markers. This vertical slice project template example paints a picture of how effortlessly you can control route registration!
How I Use This Project Template
As I pointed out earlier, the first obvious thing to mention is that this approach uses Autofac for dependency injection. This template uses Autofac simply because that’s what I’m most comfortable with! But there’s no requirement that you’re forced to use Autofac, so switch this up as you’d like.
The Entry Point Purpose
I usually like to take the approach that my entire core web application is more of a skeleton app than anything else. That is, the core web application ideally is something that’s just a dependency injection hookup and facilitates loading everything as features. The features themselves, my vertical slices, are defined as plugins that I try to migrate out of the core project to isolate them further.
If you want to move away from Autofac but still keep the spirit of the structure here, keep in mind that’s how I am using the entry point. I like keeping it extremely thin so that conceptually I need to think about all functionality being added as features. It’s not my intention to over-complicate things though. If it doesn’t fit as a feature (especially currently), then sometimes it gets dropped into the entry point. But ultimately the goal is to keep this thin!
I Like Plugins!
You’ll notice that I didn’t separate out any projects or assemblies for this vertical slice project template. And that’s me fighting against my will to make everything plugins right from the start. I needed to acknowledge that plugins aren’t for everyone.
I generally jump right to plugins because it’s a pattern I repeat over and over, and I’ve got a plugin obsession. At least I acknowledge it though! There’s little benefit to dynamically loading these features as plugins in this initial state. This is especially true if you may never even need to separate the code out into separate applications or services!
Sub Architectures
Within each of my vertical slices, I try to keep them focused on a particular domain. The result of doing this is that I have a full vertical slice through a traditional application per plugin of mine… and each sort of ends up looking like its own mini layered architecture!
And no, layered architectures aren’t the enemy… Even though we’re talking about vertical slices right now! Generally, within a vertical slice, I split things into a “presentation” (or API) layer, some type of business logic layer, and some type of data access layer. As things grow and evolve, I may need to split up my vertical:
- Into multiple sibling verticals. This is the result of a feature area representing too many things, initially.
- Into child verticals. This happens especially if I am going deeper into a feature area.
Other Considerations
What About Microservice Communication?
A common question I get when I talk about vertical slices that I want to address for this vertical slice project template is, “How do the microservices talk to each other?” Honestly, my answer might sound a bit dull. I keep things straightforward. My microservices aren’t microservices at all! They’re modular monoliths; they haven’t branched out yet.
The communication between them is plain and simple, just some basic method calls in the API layer. No flashy packages, nothing. If a need arises, I’ll design a new implementation of the API layer, probably with MassTransit, but that’s a story for another day.
So no – my vertical slices aren’t a 1:1 mapping to a micro service. However, they could represent a potential microservice within a modular monolith. And until the need arises, I won’t complicate communication more than simple method calls.
Dependency Injection
Now, on to the choice of a dependency injection framework. While this vertical slice project template comes with Autofac, you’re not tied to it. Feel free to swap it out with what you’re comfortable with. I can’t show you how to use different frameworks in the same project template since that would lead to a clash of DI technologies. However, if you grasp the concepts, adapting shouldn’t be a big deal. And hey, if enough folks are curious, I might carve out some time to show how it’s done with other frameworks.
Contract Between Core App & Features
The third point I’d like to bring up is the API contract between the core app and the plugins (which translates to vertical slices in our case). In the sample project, there’s open access to the web application from a plugin or vertical slice, which might be seen as too much freedom.
If you’re a bit uneasy about this, you could design a mechanism to manage registrations through another class. In my scenario, this wide-open access works since the plugin development is a high-trust environment; it’s just me and my team creating them. But your situation might be different, and that’s okay.
It’s Just a Starting Point
Lastly, don’t forget, this vertical slice project template is a stepping stone. There’s a lot more you can explore and extend. Vertical slices can morph into many forms as you delve deeper into your project.
Is a new feature just another vertical slice, or does it become a child of an existing one? How does this play out when we talk about plugins?
Dive in, explore, and find what works best for your project. This template is merely a launching pad for your adventures in organizing and delivering features as vertical slices. You’ll likely come up with your own flavor of this as you continue forward!
What’s Next With This Vertical Slice Project Template
Now that you’ve got a glimpse of the vertical slice project template, it’s your turn to start building! Dive into vertical slices and see how you can deliver features. As you grow your project, observe how your vertical slices are evolving. Is a new feature forming a separate vertical slice or nesting within an existing one? And when we bring plugins into the mix, how does the picture change?
The beauty of this vertical slice project template is the freedom it offers. It’s a playground for you to explore, test, and learn. The structure helps you keep things organized, but the sky’s the limit when it comes to how you shape your vertical slices. Each slice could turn out to be a mini project of its own, having its own little layers of presentation, business logic, and data access.
There are endless ways to expand and adapt this template, so don’t hold back. Experiment with different arrangements, and see how you can enhance the template to better fit your project’s needs. It’s all about learning and improving as you go. And if you’re interested in more learning opportunities, subscribe to my free weekly newsletter and check out my YouTube channel!