BrandGhost

Level Up ASP.NET Core Apps With The Decorator Pattern & Autofac

Want to learn how to use the decorator pattern effectively in ASP.NET Core? In this video, we'll see how we can leverage Autofac to incorporate the Decorator pattern (A very popular design pattern) with ease! Have you subscribed to my weekly newsletter yet? A 5-minute read every weekend, right to your inbox, so you can start your weekend learning off strong: https://www.devleader.ca/newsletter Check out more Dev Leader content (including full in-depth articles with source code examples) here:...
View Transcript
So today we're going to look at The Decorator pattern and how we can use that in asp.net core with autofac now I wanted to talk about The Decorator pattern because recently in some of my functional tests I was having a bit of a scare with how I was setting up my connections to a database and to explain this a little bit further my tests actually use Auto fact to resolve dependencies and then they're supposed to be connecting out to test containers which are going to be Docker containers spun up for my services that I need now in a testing environment I never want my test to be able to connect out to the real database or other services but because I'm using Auto fact to resolve a lot of these dependencies I'm relying on the configuration being spot on so that this works perfectly in production versus testing and call me paranoid but I just don't like trusting that things always work automatically I'd like to have a little bit more confidence in what I'm getting myself into but this was the perfect opportunity for The Decorator pattern and to explain this a little bit further I was actually able to wrap my database connections that were being create aided and only my test environment to ensure that every time I would go connect out that it would validate whether or not that was to production or to a test environment so there's many practical use cases for using The Decorator pattern and I'm not going to get into all of them because that would be impossible but I think a common one that people would start to look at is logging so if you had a logging infrastructure being able to wrap your logger in something else so what I wanted to do is walk through an example individual Studio of setting up something to do with logging in The Decorator pattern using Auto fact in an asp.net core app that was a mouthful so let's jump over to visual studio so in Visual Studio I've just gone ahead and created a new asp.net core web application and I'm going to walk you through how I'm setting up Auto fact here so just to explain a little bit we're going to start with the nougat package that we need so I'm just going to go to my solution Explorer and go over to the project to show you the package that I've included and that's going to be Auto dot extensions dot dependency injection so with that if we walk through our setup for an asp.net core app and this is using minimal apis so there's not a lot of code and that's what makes this super awesome we'll just quickly walk through how autovac is configured here and I should pause to mention that I like using Auto fact personally you don't have to use Auto fact for dependency injection it is in fact built into asp.net core however autofac is my preferred way of doing dependency injection I'm just really familiar with a lot of the methods on it and I like using it because it fits my style so the first thing that we're going to be doing in our minimal API project is creating this Builder from web application and calling create Builder these are just the args passed in from the command line in this example we're not actually using them for anything and then from there some of the magic that we require to actually get Auto fact wired up is we have to call the code that we have highlighted from line 8 to 15 here and you can ignore this part for just a moment on line 12 and 13 and what we're looking at is calling the host property and then use service provider Factory and then giving it an auto fax service provider Factory so this is going to hook in Auto fact for us and then after we can call configure services and then we can say Services dot add autovac what we have inside of here is actually configuring the container Builder which is something specific to Auto fact where we can register modules and other things to have our dependencies wired up so I'm not going to get into an extreme amount of details about how to use autofack in the normal traditional sense I'm going to assume that you have a little bit of understanding about how to call registration methods on auto fact but I'll touch on it just a tiny bit as we go through so after we have this configured and I will come back to lines 12 and 13 in just a moment we're going to create the app by calling Builder dot build and I just have this line 19 here because it came by default for when I was configuring this project just to use https next we're going to look at our route which is extremely simple I'm just providing the base route so a forward slash and what we're going to be looking at is an iMessage formatter and we're going to want to resolve this from our registered services so this is going to ask autovac for an implementation of iMessage formatter and this is a bit of a contrived example I said I wanted to talk about logging a little bit but I also wanted to show you the result right in the web browser instead of actually logging out somewhere else so what we're going to be doing is actually just calling a format log message method on this interface and then we're going to look at the implementation for that so come back to that in a moment too and then the last part if we just run the app so it's very very simple just a single route and really what the magic we're going to be looking at here is just calling this format log message method so if we go look at that we have a simple interface called iMessage formatter it just has this one method on it that we were just looking at calling and the actual implementation of this is super simple in the base case we're just going to return the actual message so there is no formatting actually happening so the string that gets passed in should be returned unchanged it's pretty boring but it's just to demonstrate the purpose of what I'm after here if you're actually thinking about how your logging is set up and maybe you want to wrap that with a decorator you might be able to insert your own formatting for example so before you actually log messages out you might want to actually do something to them first you might want to log to multiple places so you could have something like a t effect in your logging so it could log to the console log to a file log to different services that kind of thing but you can use a decorator for that and we'll look at that in just a moment the final part in the base case here is really just setting up this logging module so all that I'm doing is registering this type that we just looked at and I'm saying that I want to register it as it's implemented interfaces which is just the I message formatter that we have up here and then the last part is I'm saying that it's just a single instance so this is a Singleton and not the scary globally available herbal you know static access Singleton that you're always told to avoid and all of your coding you know it's like one of the first things you learn is an anti-pattern we're not talking about that we're just saying that every time someone tries to resolve this it should only provide the same instance before I go run this application I just wanted to scroll back up to the top and talk about lines 12 and 13 like I said so normally what we would be doing is just saying container Builder register the module and it's the logging module that we were talking about but generally when I'm building applications I like to register all the modules that are available this is going to be situational so in my cases I'm only ever dealing with modules that I've created that are going to be in the assembly that I'm dealing with or I might go scan a directory and pull in all the assemblies and pull in all the modules from there so this is just going to make our life a little bit easier when we go to add The Decorator because we won't even have to come add another module and the reason I want to show this is because when we're talking about decorators we're able to extend functionality without coming back to the core of the application to modify it in my opinion that's an ideal way to be able to do it but there's no hard and fast rule so if you wanted to manually register your modules that's okay if you wanted to add your decorator directly inside of this logging module that's okay too I'm not telling you how to do this one way or another I just want to show you that this is how I like to do it so that I don't have to come back and modify this so I'm going to go ahead and get rid of this commented line and now from here let's go run it and as we might expect the result is a little bit boring we're just hitting the default base route and then we see hello world because our log formatter is not actually formatting anything it's just returning the string that was built in okay now that we have the boring part out of the way let's go look at how we can decorate this and make it totally awesome so from here what I want to show you is the code that I have at the bottom of this file that's been commented out and hiding from us and we're going to look at that right now and see why this is so cool we're going to start with our new decorated message formatter and again it's a totally contrived example I'm just trying to show you what you can do and what we're going to be able to do in this case is take in a reference to the iMessage formatter so if you think about this in the general case our decorators are always going to be wrapping something and then providing functionality in its place so this kind of pattern is going to be very typical where we have something that we're wrapping past in and because we're going to be using Auto fan you can register and resolve other service is in the Constructor here so you have access to whatever's on the container and then in this case we can get super creative with how we want to format the message in this case I'm not super creative all that I wanted to do was put decorated right in front of the same message that comes back from the inner one that we're wrapping now we have the flexibility to not put anything here we could totally hijack this and say whatever we want you could be calling other things to go format this in different ways based on other services that you had resolved from Auto fact you kind of have unlimited options here because what we're able to do at this point is technically intercept the things that are coming in by having this decorated message formatter in place of the original one and again if you extend the thought process here if you think about wrapping loggers or maybe you want to have different Services wrapped in other things you're able to intercept or technically totally replace other things going back to my example from the beginning what I was able to do is if this was something like connecting out to a database I was actually able to say what's the connection and string that we're using let me check to make sure it's safe and if it's not I can fail the test immediately and not actually allow database connections so that was a very specific use case of a decorator being used in my testing scenarios but the options are technically Limitless now to make this work we're going to leverage something from Auto fact that's built in called register decorator and I'm just going to clean this up a little bit so it fits on the screen here but the Syntax for this is that we just call it registered decorator on our Builder so like I alluded to earlier I do have a new module for this but we could have jammed it in the original one as well I just wanted to show that we could actually have this in a totally separate module and then when we call register decorator we're going to say as the first type argument the wrapper or The Decorator that we want to use and the second type argument is going to say basically when someone tries to resolve this service we want to decorate it with the first type parameter so in our case anytime someone tries to get an iMessage formatter and the original one that was registered registered was just the logger one the standard one then we're going to wrap it with this decorated one and auto fact will take care of that magic for us and in fact when it goes to create the decorated message formatter it will pass in the one that it needs to wrap all for us automatically and if we jump back to something that I talked about right near the beginning of this video well if we look back here because I was able to actually say register assembly modules and just look at all the modules in the current assembly the cool thing about this is I don't have to come back here and change this code at all I don't have to go explicitly register another module for the new code I added so if you think about this I talk about plug-in architectures a lot and what I like about plug-in architecture is that we can extend applications without having to touch the base application this is a nice parallel to that because I'm trying to demonstrate here that we never had to come back and touch this code to go decorate our message formatter and I'm going to demonstrate that now by running the application all right it's slightly more exciting this time just because it says decorated in front and we know that that means it must be calling The Decorator class before it's actually called in the format message I admit it's a little bit of a boring example but I hope you can see that we have this original message coming back from our standard one and like we saw in the code it's able to generate this part first and then in the string formatting it inserts this text into one with a placeholder directly after the word decorated with a colon and to reiterate one of the most awesome Parts about this is we never had to go back and change the core application we literally just added a new class and a new module and everything was taken up for us automatically alright that's going to wrap it up for today's video and what we looked at was our ability to create decorators in an asp.net core application using Auto fact and what we saw is that we don't actually have to go modify a core application when it's set up in a particular way and that way we can go extend functionality my wrapping classes and we can either replace the functionality we can use a version of it the choice is yours it's kind of you know seemingly infinite but we can add this new functionality or change it without having to go modify the core original application now if you structure things in a slightly different way you can manually register your modules there's nothing wrong with that the choice is yours for how you'd like to do that but if you use some of the methods I showed you today you can actually have that taken up automatically there might be cases where you don't want that because you want to have more control over what's being loaded perhaps security reasons or maybe versioning for dlls and things like that I'm not here to tell you the right or the wrong way to do that everything will be situational but today we looked at The Decorator pattern and I hope that you can find some interesting use cases in your asp.net core apps thanks for watching and we'll see you next time

Frequently Asked Questions

What is the Decorator pattern and how is it used in ASP.NET Core?

The Decorator pattern is a structural design pattern that allows you to add new functionality to an existing object without altering its structure. In ASP.NET Core, I used the Decorator pattern to wrap my database connections in a testing environment to ensure they connect to the correct database. This approach helps in extending functionality, such as logging, without modifying the core application.

Why do you prefer using Autofac for dependency injection over the built-in ASP.NET Core options?

I prefer using Autofac because I'm more familiar with its methods and it fits my coding style better. While ASP.NET Core has built-in dependency injection, I find that Autofac provides more flexibility and features that suit my needs, especially when working with complex applications.

Can you explain how to register a decorator in Autofac?

To register a decorator in Autofac, I use the `RegisterDecorator` method on the builder. I specify the decorator type as the first argument and the service type to be decorated as the second argument. This allows Autofac to automatically wrap the original service with the decorator whenever it's resolved, enabling me to extend or modify its functionality seamlessly.

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