BrandGhost

Head to Head: Registration Callbacks With IServiceCollection And Autofac

If you know me you know that I love this ONE thing in C#... Autofac. It's probably my favorite nuget package that we have access to. But this love for Autofac was started many moons ago when I needed to scratch my itch for dependency injection and there was simply no better option. Fast forward a bajillion years and we have a contender... IServiceCollection is the build-in dependency injection framework that we have from Microsoft and it's come a VERY long way. So let's compare how we do registration callbacks between these two frameworks.
View Transcript
if you've seen my other videos then you know I'm a huge fan of autofac but honestly I am trying to convert myself over to using I service collection hi my name is Nick centino and I'm a principal software engineering manager at Microsoft I love writing C applications using dependency injection building plug-in systems and historically I've used autofac because it has been so much further ahead than I service collection however over time that Gap has absolutely been closing and at this point in time I'm starting to find that when I'm building ASP on at core apps when I'm using autofac I'm fighting against some things that should be a lot easier with I service collection in this video I'm going to walk through a very basic registration technique that's common in autofac I use it heavily and how we can translate that over to using I service collection because in the examples I've seen it's not as common that we see this with I service collection a quick reminder that if you like this kind of content subscribe to the channel and check out that pin comment for my courses on dome train with that said let's jump over to visual studio let's check out I service collection and autofac and compare this registration technique all right so on my screen I have some autofac code for setting up a dependency container I do want to mention that if we go into look at the project here that I do have autofac added and I do have the Microsoft extensions for dependency injection added as well if you're building as speed on it core apps I believe that you are getting this included automatically this is just a console application so I did have to go add that manually myself and then of course with autofac that is not included so that's all also been added all right so this example code is very simple we're going to start off with the autofact pattern here for creating a container Builder this is going to be the thing that allows us to create our registrations and then I have a registration here that is a little bit more complicated than we might see in the traditional sense traditionally if we were to try and register something that was essentially just going to be my type here so some type that we want to register the way that that might look is we would say Builder and we would ask it to go register the type exactly as it is you can see that co-pilot is guiding me along here but you'd have a registration that looks something like this right you could say register the type give it the type itself you can say as self or you can exclude it in this case it will be the exact same thing but as self just explicitly says that when you were registering this type if you want to resolve it you need to explicitly ask exactly for the type as it is and then single instance makes it such that when the next person goes to request this it will just give you back that same instance the code that we have below is very similar in nature but one difference is if we go look at the type itself jump over to that definition we can see that it has a primary Constructor so it takes in one value just called Su value then there's a property for it as well the tricky part here is that when we're just going to use the typical syntax like we see on line 12 here when we go to resolve this type at runtime which would occur down here on line 24 we're asking the dependency container hey go get me my type right we ask for it when it goes to try and resolve it it needs to look at the requirements on the Constructor for my type again if we look here we can see that we have a primitive passed in so string is just a primitive type that would mean that we have to have a string registered on the dependency container and it's kind of weird because when you go to do something like this it's not a really good pattern to just have a random primitive that's been registered on the dependency container because if you have more construct taking in more Primitives you can imagine that you're going to have a lot of complication that comes about with that instead and this is a really simple example right what I'm doing here is I am explicitly setting up my object you can do this in different ways as well sometimes your configuration might not be just as simple as passing in a string you truly might want to do some configuration and pass that in and your opinion might be that if you explicitly have the registration broken out like this it makes your easier to understand there's no right or wrong here so if you wanted to have more verbose construction here this is your opportunity to do it with this syntax which is just register it gives you the component registration context so if I hover over this you can see I component context it does allow us to go resolve other things so we could ask the context to go resolve if we had other dependencies we could go ask for those things here before we move on this is just a reminder that I do have courses a available on D train if you want to level up in your C programming if you head over to D train you can see that I have a course bundle that has my getting started and deep dive courses on C between the two of these that's 11 hours of programming in the C language taking you from absolutely no programming experience to being able to build basic applications you'll learn everything about variables Loops a bit of async programming and objectoriented programming as well make sure to check it out there is something that I'm not going to spend time on but if you're curious about it there is another opportunity here that I won't go into a lot of detail on but you can have these Factory delegates so that way if you had say my type has three more services that are dependencies that need to be passed in but only some value as the string is this configurable one that we need to do and we can't get that off the container we could go make a delegate function to go work with that I can probably make a video on that in the future if you want to see it but for now this is just a registration call back that we have to go do some more verbose setup hopefully you can see what that pattern looks like and understand how it works and like I said the single instance is just tacked onto the end like we see in the traditional way from there that's our registration that we have on the container in autofac we need to say go build that container so we get that and then you don't have to do this line if you don't want to but this is to get a lifetime scope if you're managing different lifetimes and then we can resolve the type so either off the lifetime scope itself or directly from the container container but at that point when you call this line on line 24 autofac will go create that instance for us doing what we just walked through we'll go run this code and then from there we're going to print out some value to the console if I go put this in place and we run the autofac example we should be able to see something very basic but we see hello from autofac and that's because we do pass that in here okay so very simple autofac example traditionally when I'm writing code I will have a combination of things that look much like this registering things with their implemented interfaces is a lot more common for me as well but I also have this kind of code sprinkled around now we're going to go look at the service collection stuff that's built in for dependency injection in C so what that looks like if we scroll down here is very similar right and the thing that I wanted to call out because I don't see it used a lot is that with service collection when we create a new one this is the call that we need to make to basically go get the same type of registration call back like we see here because again the typical way that we might do that is we have services and we would go say something like add Singleton but this is going to have the exact same problem that the original autofac one had right so if I scroll up this code is not going to be able to execute properly because we don't have a primitive string type assigned to the container and in my opinion it's probably not great practice just to go register a random string primitive on on your container this is going to have the exact same problem as the line I just deleted above in the autofac example but this add call that we have right here essentially gives us the same abilities that we saw in the autofac example so we say the type that it's going to be returning so when we make a new service descriptor we say this is the type if people are asking for this this is what they should be getting when we go run this code this is exactly the same as what we see up here from lines 15 to 17 it will match 35 through 37 I'm just changing the string so that when we run these examples we can see this one is coming from the ey service collection from there the only last thing that we have to mention is the Singleton part but not very special right it's just kind of like what we saw when I had it here I guess that's not the right thing co-pilot this would have been my type right so single and up here we can see that I'm doing single instance same concept nothing fancy just showing you the syntax from there we have the service collection completed so we've added our one service that we're interested in we go ask to build the provider and once we have the provider much like the container from autofac we can go ask for that required service from there we just print out the value to the console if we were to look at both of these the big difference is just that we're using different Frameworks but the pattern that I wanted to show you is that we have this opportunity to have a registration call back that's kind of generic feeling we can write whatever we want in the the call back and we have that in both of these Frameworks if I go run these both together we can see that we hopefully get two different outputs we see one from autofac and one from the I service collection so there's the autofac one and if I scroll a little bit lower we can see I service collection same Concepts different Frameworks now I did mention that I've spent a lot of time working with autofac years and years working with autofac and at this point it's basically one of the first things I do when I'm creating a new C application I just go add the autofac N get package start making my dependency container and moving on but I am trying to get more familiar with I service collection but it's almost like muscle memory I need to make sure that I'm saying hey look don't add autofac start with your service collection and this is one of the things that's kind of holding me back because I'm not used to doing this pattern with the service collection but there is one more thing that autofac in my opinion does super well and I'm not quite ready to switch over until we go look at this next video to see what we can do check it out

Frequently Asked Questions

What is the main focus of this video?

In this video, I focus on comparing the registration techniques between Autofac and IServiceCollection for dependency injection in C#. I share my experiences transitioning from Autofac to IServiceCollection and demonstrate how to register services in both frameworks.

Why should I consider using IServiceCollection over Autofac?

I believe that while Autofac has been a powerful tool, the gap between it and IServiceCollection has been closing. I've found that using IServiceCollection can simplify certain aspects of building ASP.NET Core applications, making it easier to manage dependencies without the complications that can arise with Autofac.

What are some best practices for registering services in dependency injection?

When registering services, I recommend avoiding the registration of primitive types directly in the container, as it can lead to complications. Instead, I suggest using more structured registrations and taking advantage of registration callbacks to manage dependencies more effectively.

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