How to use Autofac for Dependency Injection in C# dotnet
April 3, 2023
• 7,026 views
You've been leveraging composition like a good software developer, but you're finding that the entry point of your program is becoming a mess. Fear not! In this video, we'll look at how we can use Autofac to implement dependency injection and make your program nice and organized!
Want the source for this video? Check it out here:
https://github.com/ncosentino/DevLeader/tree/master/RefactoringCompositionDITesting/RefactoringCompositionDITesting.CompositionRefactor1.Autofac
For more information...
View Transcript
alright so you've been working with composition a little bit more in your code and now that you've been refactoring a lot of stuff to take advantage of composition you're realizing that you have a really big problem the entry point of your code is now hundreds or thousands of lines long and it consists of just instantiating new objects and passing them into other objects you feel lied to composition was supposed to make your life easier but what is this mess that you have at the top of your program well fear not because we're going to look at dependency injection and in particular one of my favorite Frameworks for this if you haven't watched my other videos on composition or aren't familiar with that yet please go check those out first come right back here and let's go jump into the code alright on my screen I
have an example of a class that is built up of smaller classes to demonstrate composition on the surface this might not seem so bad because we only have one instance of URL saver and we can just instantiate these dependencies one time in one spot but if you've been following composition like this like I said in the beginning of this video you might have found that you have code that looks like this times 10 or 100 at the start of your program I just wanted to quickly illustrate how fast this can balloon out of proportion if you don't have some tools to help out with it so on my screen you can just see that I've introduced some really simple dummy classes called some composed class and some compose Class 2 they don't actually do anything but they do take in one of these awesome URL
Savers as a single parameter and then just store it as a field so this is totally contrived code so don't pay attention to the details here but let's go see what happens when we try to make some of these composed classes alright so these examples are a little bit contrived but let's pretend you have some spot in your code quite literally I've just named a function called that and let's pretend that this method's responsibility is to go create an instance of some composed class and return it to the caller if this part of your code did not actually have access to some shared URL saver that is going to be be one of the dependencies for this class then you would have to go actually create the whole thing from scratch if you consider now that you might have a block of code that looks
like this and maybe at your entry point you still have code that looks like this too you now have two spots that completely duplicate the code and that's already six lines of code duplicated twice for something that seems very straightforward now let's pretend you have yet another spot in your code and this one is actually going to create some composed Class 2 and then call the do stuff method on it again if you didn't have access to this URL saver that is a dependency for this class you would have to go create the entire thing again now you might be sitting there saying well Nick what if I already have access to this URL saver I Can Go pass it around and you're totally right if you have access to it it will make this a lot more simple but I'm just calling out that
if you have particular places in your code where you have to go instantiate these things things suddenly you have this pattern duplicating across your code base and furthermore even if this code isn't scattered across your code base depending on the size of your program this type of thing like I said at the beginning of this video if I go right back to the entry point of our program you might actually have a hundreds or thousands of lines long just instantiating things to pass them into other objects so like I said at this point you feel duped because composition was supposed to make all of your code cleaner and it's made big improvements for you but you still found that basically it just moved the problem to the entry point of your program we're going to fix that with a tool called autofack I've gone ahead
and installed a nuget package called autofax so right at the top of this file if I say using and then Auto fact we can see that we have access to this namespace now what Auto fact is going to allow us to do is actually register the different classes that we want to have access to and then Auto fact will will as the name suggests automatically create the objects that we want to have access to it does so by mapping the dependencies that each of these classes have so when we go to ask for one of these instances it's able to go then resolve the dependencies automatically for us so if we had hundreds or thousands of lines of code long like this let's go see how Auto fact can help transform this to be a lot more organized for us in its simplest form autofac
is going to allow us to create what's called a container Builder and this is going to be so that we can create a dependency container that might sound a little bit confusing but all that we're going to do with that dependency container is register our dependencies to it you might see this referred to as registering dependencies or registering services and that might depend on whether or not using Auto fact or some other dependency injection framework once we've finished our registration we're actually going to ask the container Builder to go build that container and then we can assign it to this variable it is disposed so we'll put a using in front of it and then with that container we can begin a lifetime scope and then actually start resolving things to get our instance so let's go look at what's required to actually go register
stuff all right so autovac organizes things into what are called modules and we're able to create lots of these modules to help organize our code depending on the different domains or other ways that we want to organize our dependencies in a module all that we need to do is actually override this load method which has a container Builder on it from there we can actually start registering our dependencies the container Builder follows this type of syntax that allows us to chain different operations together so you can see that I'm registering the type called awesome URL saver and I'm also marking that we only want a single instance of it however if we go looking a little bit deeper you can see if you go try this on your own because it's very small on my screen that we can actually call other things that allow
us to change how this registration works now that we have have our module created and we've registered our awesome URL saver we can go have a look to see how we can use that the container Builder itself has this register module method on it and we can actually pass in the type parameters or a module there's plenty of other methods on the container Builder that can allow you to register modules in different ways including scanning assemblies and loading things from disk if that's made you curious then stay right to the end of this video and you can watch how this works now that we've registered our module we can actually try to get the instance of our URL saver to actually get the instance of our URL saver we just asked the scope to resolve the type that we're interested in which is awesome URL
Saver in theory this is all we need to be able to do to refactor our code for using autofac or is it well what happens when we go run this when we're debugging and we go to resolve this URL saver if I press F10 in Visual Studio to step over this line You'll see that it's complaining that we can't actually resolve this dependency it tells us very clearly that there is an exception trying to activate the awesome URL saver type and if we scroll a little bit lower it says None of the constructors found on that type can be invoked with the available services that we have going a little bit deeper it tells us that it can't resolve the parameter URL normalizer for the Constructor that it found on that type and if you think about it that actually makes sense because the only
thing that we registered in our container was awesome URL saver Auto fact at this point has no idea about the other dependencies that we're interested in that means that we have to go register those types as well so fortunately for us that's a really simple exercise to just go register them right in here all right I've gone ahead and registered the other dependencies that we needed to go create an instance of awesome URL saver and again I wanted to point out that I am calling these other ones with this single instance method on them as well this just means that the container will only have to generate one instance of this type because I know personally these individual classes don't carry any state and there's no reason for me to have to go create new instances of them it's not like the Singleton that you're
probably thinking of that has some globally accessible shared state that can be modified that's usually the type of Singleton that we want to avoid if we debug this again with all of our pieces registered and now press F10 to step over the scope resolve line we can see that if we check the URL saber and the text is very small so I apologize it does have an instance of that type for us and this program doesn't actually write anything to the console but you can see if you read the text in the console that we had no exceptions and the program actually ran successfully having a quick look back at the entry point of the program you can see that we replaced all of the custom instantiation with a few lines of Auto fact creation for our container and to clarify it's not that we
just deleted all of the other instantiation it's just that we modified it to pull it into modules and this will allow us to organize our code however we would like and that's just a quick example of how you can use Auto fact to clean up a lot of the code that you have that took advantage of composition personally for the types of applications I write now I can't even try to write normal code without using Auto fact to do my dependency injection I find if I'm prototyping things and get to roughly about a hundred lines of code in my program that are just instantiating things before I start doing any work that's usually about where I'll switch over to Auto fact and start organizing my code to be a little bit more clean and as I mentioned autofack is able to do some really powerful
things so we only looked at registering a single module in our code for this example but because you say right to the end of this video if you watch this one right here you can actually learn about how you can do plug-in loading with Autofab
Frequently Asked Questions
What is Autofac and how does it help with dependency injection in C#?
Autofac is a dependency injection framework that helps manage the instantiation and lifecycle of your classes. It allows you to register your dependencies in a container, which then automatically resolves them when needed. This helps to clean up your code by reducing the clutter of manual instantiation, especially when dealing with complex compositions.
How do I register dependencies using Autofac?
To register dependencies in Autofac, you create a container builder and use its methods to register your classes. You can organize your registrations into modules by overriding the load method of a module class. Once you've registered your dependencies, you build the container and can resolve instances of your classes as needed.
What should I do if I encounter an error while resolving a dependency in Autofac?
If you encounter an error while resolving a dependency, it usually means that not all required dependencies have been registered in the container. You need to ensure that all dependencies required by the class you're trying to resolve are registered. This may involve registering additional classes or services that the main class depends on.
These FAQs were generated by AI from the video transcript.