BrandGhost

FREE Vertical Slice Project Template - ASP.NET Core + Autofac

By popular request, here is the project template that I use for creating vertical slice architectures in ASP.NET Core. This is something that I use and adapted to be slightly more generic. Is it the perfect vertical slice project template for you? I can't claim that! But I go into details about how I leverage this, and how you can adapt it if you like it. Here's the repo: https://github.com/ncosentino/DevLeader/tree/master/AspVerticalSliceTemplate Have you subscribed to my weekly newsletter ye...
View Transcript
so you've been watching videos and reading articles about vertical slices and you have people like me and other creators that are talking to you about the benefits of structuring your code for vertical slices and how vertical slices can help you with more rapid feature delivery but one of the problems is that you're still not totally sure how to get started because it's a lot of information and it's not exactly how your project is set up well by popular request I've had people reaching out to me asking can I share a template for setting up a project for vertical slices and while there isn't a one size fits-all solution for this I have created a basic solution that I would like to use that leverages autofac sets itself for vertical slices and plug-in development all in one I'm going to walk us through that code in this video and I'm going to have a link in the comments to GitHub where you can go clone this down and create your own versions of a vertical slice architecture optionally with plugins and then develop software using this method and as I go through this video I will remind you and I want you to keep it in mind that this is is not going to be a one siiz fits-all so I will talk about how we can leverage this and also some of the challenges that you might have and how you might want to tweak things to get other Behavior out of it and of course enough blabbing for me let's jump over to visual studio and check it out all right so on my screen right now I have the entry point to our vertical slice template project that we can work with and if you're scanning right now with your eyes you'll probably notice that I am leveraging autofac to be able to do this so now this is my preferred dependency injection framework you'll see in a lot of my other videos that I leverage autofac you don't need to leverage autofac but this particular template is going to be leveraging autofact so that's the first call out that I want to make the next call out that I want to make is this comment right at the top so all of my newsletter subscribers were able to see this video and a dedicated article ahead of time so just something to keep in mind that if you want to see this type of content a little bit early you can subscribe totally for free and I'll have a link to that in the comments as well all right for the actual code to to get this going we're going to start by creating a container Builder with autofac so that's going to be setting up our dependency container but the very next thing we're doing is loading all of the modules currently in the assembly that we're working in and if you're looking at the project layout there is only one project right now and that means that if we go to load all of the modules for autofac from the current assembly then we're going to get everything all at once so I have this comment left in here as it to do so if you're breaking out different projects that you want to have modules loaded from you'll need to tweak this in particular right here lines 16 and 17 to make sure that you're pulling in the modules from the expected places and you can certainly do this manually where you explicitly list and load every module by hand that you want to have loaded in or you can follow one of the videos that I will link above to be able to detect these automatically from a file and folder structure and then load them in more dynamically the rest of our startup code right here is just to be able to create the dependency injection container and get a lifetime scope from that from there we're going to resolve the application and then just run it at this point the main entry point is going to block on this call to run the web application but if you're familiar with asp.net and looking at line 21 you're probably wondering what the heck a configured web application is and that's something I've made so if it's not familiar don't worry we're going to jump into that next so in order to understand where this configured web application class comes from we're going to go ahead and jump over to the only core module that we need for autofac to get all of this working which is web application module and let's walk through what we have in here before explaining each individual registration I just wanted to take a moment to explain the layout of why I have the registrations in this format now part of this is done because I wanted to feel more like a reusable template for you and it might be slightly overkill for a really simple project and you don't have different configuration that you want to do but because I want more than one person to reuse this in more than one instance I've structured this in a way that you have opportunities in different parts of the code organization to be able to configure things how you might want so some of the flow is going to look like creating a web application Builder and then once we have that Builder we're going to use the Builder to create a web application and then once we have the web application we're going to want to be able to do certain things like registering routes and other configuration before we actually go start it up so the different registrations that I have that we're about to walk through they're going to be laid out such that if you're like I want to change something at this point in time cool you have a part in the code that you can go add some customization to so I could have collapsed this into something uh you know like a single method or something like that but I felt that by separating it out into these different areas that you have more targeted spots to go do your configuration so our very first registration is going to be creating the Builder for a web application and then registering that to the dependency injection container just a quick note that this is able to pull in the command line arguments so while we're not in the top level entry point of the application we can still fetch those from the environment static class the next part of our registrations is going to be pulling out that web application Builder that we just registered and like I was saying prior this is a spot where if you wanted you could go customize how you want to set this up by adding more code here but in this example we don't have any custom code so what we'll be doing next is just building that we application and then returning it so this registration is to get us an instance of the web application and you'll notice so far that both of these have been registered as a single instance and that's because for the lifetime of our application we only ever want one of these things to exist when we resolve it this final registration gets a little bit more spicy and requires a bit of explanation to understand it part of how I set up this template to be reusable and have vertical slices introduced is by allowing the different vertical slices that were caring about to register their own routes now there are tons of different ways that we can do this and as you're reading this code on screen and hearing me explain it you might have your own opinions about how you want to do this and that's totally cool but I can only make one template at a time and this is one of the templates that I like to use because it's pretty simple for me so the way that this works is that we're going to be asking autofac to resolve all of this type right here called route registration dependency marker and this is just a marker class so to you it might feel a little bit hacky that we have to do this in order to get our registrations but what this is allowing us to do is have opportunities for different autofac modules to go register their own routes to our application and I'm going to pause there for a moment so I can talk a little bit with my hands because it seems a little bit easier for me to explain things but when we're talking about vertical slices which is one of the reasons that you clicked on this video we're talking about being able to deliver features in verticals and when I think about developing web applications and in particular web apis some of the vertical slices that I look at at a high level are the different routes that we're interested in now depending on what type of application you have maybe you have something that's like a checkout application you might have like a customers uh base rout and then like a cart and a products kind of thing like these might be highlevel routes that you have and the way that I might start organizing these is by individual features for each of these but from there you're going to have other routes that are part of those and you could go ahead and again make this like a subsection of verticals or other plugins it really depends on how granular you want to get with this kind of thing in my opinion it starts to become Overkill at some point if literally everything is a Plugin or a vertical and that's coming from someone that loves doing this kind of stuff if I had my own way writing my own code all the time I would probably take things to an extreme like that that but there is diminishing returns at some point if you had a plugin for every single possible route that you were registering it would probably feel pretty cumbersome and pretty complex to navigate so at a high level how I like to organize things is a vertical for each of the different major routes that we have and then that way the sub routes within that generally seem to fall into place in the same plugin now the more complex that gets like if you had different backing implementations that you wanted to start in into that route you might then go split that into other verticals other plugins but to get started I feel like the high level here is is this approach or we have sort of a feature for each of the different major routes that we're looking at so we'll dive into one of these specific examples because I've included one in the template just so you can see it and we'll see how it registers a route so let's go check that out now so to see an example of how something like this would get populated we're going to go look at the different features that I've included in this template and you don't have to name your folders like this there's no requirement that it has to be labeled features for this folder and that you have feature one feature two but this is just an example of how I like to organize things so there is no feature two in this I just wanted to show you a folder for it but we're going to go check out feature one which is just going to have its own autofac module and again just a reminder that this whole sample application this entire template is set up such that we have autofac being able to populate all of our different Plug-In or vertical slice information this one is going to have this one is going to have strictly just a hello route you might want to have something like mapping your groups here and if we had a group for that top level route we might have some of our other sub routes look something like this and yes I'm using minimal apis here and it's worth calling out that there's a little bit of a catch with the dependency injection framework the way we have it set up now this is going to be slightly complicated and it might not make sense until you go running this entire sample application to see how it works but I'll try my best to explain what's going to be going on here if we jump back to the program we'll see that we're using a container builder at the high level to create our application however in the current setup the actual application that we end up configuring is not using autofac as the dependency injection framework for itself and that might sound a little bit confusing but our program is using autofac to go set up a dependency injection container and get all of our dependencies wired up but the actual asp.net core web app that we end up creating is still just using the built-in Microsoft dependency injection framework there are tricks that we could do to go enable this but I'm going to explain how I end up structuring some of my code to not have to worry about that anyway so a situation that might come up and cause you some grief is if you're expecting to have this type of syntax in your minimal apis and that's because as I said If you're trying to wire up all of your dependencies on this container Builder the actual asp.net core application is not not going to be getting these dependencies from autofact you would have to do additional setup to accommodate that however what I find in practice is that minimal apis are great for prototyping something quick and when I go to actually scale out my application that's not how I'm going to end up creating my syntax and that's because I'm not going to end up having all of these routes in this registration I'm going to be pulling them out into other classes to have them be better organized and as soon as I end up doing that any type of service that I would want to have on the route just like this I end up replacing with just the route parameters just the things I need provided on either the query itself or in the route and any type of service I'm going to have dependency injected through the class Constructor so this type of thing in order to support it we would transform it as the following so what we would do instead is resolve that service up here so if you're not pulling stuff out into another class just yet the way that you would transform this this type of syntax and having it on the minimal API is to resolve it right from the dependency injection container here so we would go resolve that service then we would get rid of this syntax Al together on the minimal API and what we could do then is if this code here on the actual API itself was requiring this service we would just reference this variable right here when you go to migrate this code out into another class altogether you can just pass in this service as an interface or a concrete class right on the Constructor and then because that class would get registered to The autofac Container we'd be able to resolve this automatically so just to clarify you can't use from services in this fashion if you're just registering everything to the autofac container and that's because the asp.net core web app itself is not using autofac as the dependency injection framework so I don't want that to be misleading to you you can go go ahead and configure things other ways but if you use this template that's how it will behave and with all of that said if I just revert that code that I was showing here the thing that we were trying to point out before is where this route registration dependency marker comes from and we're using this as a marker to say that once we've finished registering all of our routes for our module we'll go ahead and return this marker and the reason that this is going to work for us is that when autofac goes to ask for all of the registered markers of this type it's going to for the resolution of all of these register methods that do return one of these and that means if we had one two or n number of modules that had this type of behavior where they're registering routes all of them would get the opportunity to go register those routes and just to call it out again this is how I've structured my code you don't have to do things this way but that's how this template Works you're going to have modules that are allowed to hook in right into the Bas application and register their routes if you're thinking think about vertical slices and plugins I've talked about this in my other videos where you want to consider the API contract that you have between a Plugin or something like a child module so a vertical slice still fits this definition right here so you'll want to think about how that looks and how you want to structure it in my example I'm essentially giving full trust to a plug-in or a vertical slice that I want to go develop by giving it the entire application reference and saying go do what you want with this so it's intended to be go register routes but because I'm giving it the full application it could go do other things too if you're nervous about that and you don't want to give full control you could tweak this type of thing to not allow the vertical slices or plugins to be able to resolve the entire application instead you might go create an interface or a class that allows you to provide that functionality very specifically to other verticals to say hey go call this method on this class to register your routes but I don't really have that fear when I'm developing stuff for myself uh and if I'm working with teammates that I trust I trust that they're doing the right thing too but of course if we're able to it makes sense to try and restrict things from allowing people to make accidental changes and abusing some of the apis that we have so I wanted to call that out because that's how I've structured my template it works for me and if you're reading it going that makes me nervous you can tweak this to make that behavior the way you want okay so this is the end of feature one we've talked about how we can register our routes here for a particular vertical in this case that vertical is feature one and it's also structured like a plugin and that's the end of the single registration we have and this route registration dependency marker is going to be one of potentially many that we would have coming from different verticals and that's going to jump us back to our core module so line 24 here will for force that resolution to happen it's going to force all of the verticals that do that registration of a route registration dependency marker to complete so that means at this point in time by the time we hit line 26 anything that needed to register a route has done so so what we can do from there is go pull our web application instance from the container you can do other configuration that you might be interested in right at this point with the web application so for example this one on line 27 is just using https there's lots of other configuration you could do at this point and then this is going to bring us right back to this configured web application class that we were talking about right near the beginning of this video the reason that I've created this separate class which is really just a record with one single property which is the web application it's extremely basic but the reason I've done this is arguably just a little bit of a hack as another marker that we can have and that marker is that we are resolving that web application but it's at the point where it's configured and that's because if we try to resolve it any earlier we might be short circuiting this logic up here and because we want to ensure that all of this has happened before someone actually goes and tries to start the web application we're using this configured web application to say once you're trying to resolve this we're guaranteed that anything that you needed to configure has been performed at this point so at this point if we jump all the way back to program.cs and you see configured web application here back to my previous point it means that the entire web application has been configured so we can just go ask for the web application instance to go run it at this point and that's the summary of how this template works if you go to use this and you want to start adding more verticals the way that you might do this is cloning what you see in that feature one folder that has a module and extending things that way at that point you'll notice that as you continue to build out your features in those verticals that I was talking about recall what I said earlier in this video as those grow and complexity you may want to start doing other verticals within your verticals but at some point if you're following that and leveraging plugins and having different projects and doing Dynamic dll loading it might get more and more complex to a point where you're making a tradeoff that's not really worth it so for me what I found personally is that I start with these different major verticals and then a layered architecture starts to emerge within that vertical and you might be hearing that going well wasn't the whole point of vertical to make sure that we're not going to be running into layered architectures and yeah for the most part but the vertical slices that I'm getting at the top level a lot of the time what I find emerge within that are these situations where I need some sort of shared context so the entities that I'm working with they all make sense within that vertical and if they start to KN I might actually have a vertical that I need to pull out of the vertical that I'm working in so this is all going to be something that evolves but starting with a template like this I feel like gives you some opportunity to make that all happen and if you thought this was interesting I'm going to link above one of the source videos that triggered a lot of this conversation so you can go watch that next if you haven't seen it thanks and we'll see you next time

Frequently Asked Questions

What is a vertical slice architecture and how does it benefit software development?

Vertical slice architecture allows me to structure my code in a way that focuses on delivering features rapidly. Each vertical slice represents a specific feature or functionality, making it easier to manage and develop software incrementally.

Why did you choose Autofac as the dependency injection framework for this template?

I prefer Autofac because it offers powerful features and flexibility for managing dependencies. While it's not mandatory to use Autofac, I find it enhances the organization and scalability of my projects.

How can I customize the vertical slice template for my own projects?

You can customize the template by modifying the code structure and registrations as needed. I’ve designed it to be flexible, so you can easily add or change routes and configurations to fit your specific requirements.

These FAQs were generated by AI from the video transcript.
An error has occurred. This application may no longer respond until reloaded. Reload