YTread Logo
YTread Logo

C# Dependency Injection with Autofac

Jun 09, 2021
Dependency

injection

can be a really confusing topic, but when done correctly,

dependency

injection

can be one of the best things you can do for your application, it allows you to disconnect parts of your application from each other easily and allows you to test the different parts of your application independently today I can help you get started with

dependency

injection using a free tool called Auto FAQ. We will look at a small sample application and first apply the dependency inversion principle, which is the D in solid, then we will connect Auto fact to handle the connection. several dependencies together if your newest channel my name is Tim quarry and my goal is to make learning c-sharp easier.
c dependency injection with autofac
This channel is full of videos explaining the different parts of c-sharp. I also have a website where I offer complete courses on c-Sharp and sequel, one of the things I recommend is that you practice what you have learned in a real world application. As of this recording, I have two different start-to-finish courses that do just that and there are more on the way if you want to see how various things you learn fit into a real application. Check out those courses on I'm Tim Quarry. Don't worry, now let's start with our example project, since with all my recent videos I have uploaded this source code as part of a blog post on the topic, make sure to follow a link in the description to get that code.
c dependency injection with autofac

More Interesting Facts About,

c dependency injection with autofac...

Now here I have a console application and a demo library which is a class library. Well, I just started, it's really simple. The application we have here is in the CS program. We have this kind of business logic being instantiated, so we say business logic equals new business logic, then we say process data and that's it. Now, if we use business logic, process data does a few things first. it's all news, two different instances, one for the logger, one for the data access, this says that the logger starts the data processing and then processes the data.
c dependency injection with autofac
Now keep in mind that you only have one console. Writeline, this doesn't actually go out and do anything, it's all just a console. write line to simulate doing something then it says process the data and then we load some data and then we save some data called processed information and then we record that they finished processing the data so okay now let's look at the data access really simple if you call a load data method it says load data, if you call a save data method it says save every time you pass in the longest console. writeline x' records any messages you passed, okay, it's very simple, let's write very quickly and I'll do it. put it over the other screen here so you can see it, that's all we do, log in to the data processing, process the data, load the data, save the processed information and then record the finished processing of the data, okay , this application simulates performing many different actions. that we make a real application, but it doesn't actually include the complexities of making them, so even this basic skeleton of an application gives us a good idea of ​​what an application could do, well, it boils down to the simplistic version. of this and the reason why I made a simplistic version and not a real application is because in this tutorial is the tutorial and we are only focusing on how we do dependency injection using Auto FAC, that is our ultimate goal, so we're just getting started.
c dependency injection with autofac
With something that simulates what we would normally do, we know right away that we have some problems if we subscribe to the dependency inversion principle which is the D in solid, for example, here in business logic we met two different instances, one for the logger and another for the data. access, that means we rely heavily on these two elements, okay, so this process data method, this business class logic class, they are directly linked to these two utility classes, okay, we can't disconnect from no way and if we wanted to replace, for example, the logger, I have to come here and change this right here for something else, okay, then the Pennsy investment principle says that's the wrong place to do it.
Instead, we should let a chain emerge and program ICS or one of its high-level object controls. All this new now, if you've seen that solid video. I made a De Sala video on the dip dependency inversion principle. You understand you know what we did in that video. We create a factory that when you request a business logic class. give it a new instance of business logic and so on, we are going to do something similar but not exactly the same, but let's start by first preparing to prepare for those things, this is really easy, okay, so we need to create interfaces for all of our classes that way we can change them later if necessary, so what we are going to do is select the name of the class itself or click on it somewhere where we press the checkpoint, the last option is extract the interface and It says I am going to create an ID to access and if I am going to have a low load data and a method to save data, press OK and now we have our public interface ID to access with load data and save data and they both match. above we have and now we implement the data access interface I okay so it's really simple you really have to do anything else there so let's go to a logger and do the same thing or create an interface for this and once again for the business logic, so we create an interface for each of our classes, very good, I want to add to our configuration of the dependency inversion principle, eventually our dependency injection system is fine, so that is step number one, step number two is a stop, depending on whether they declare at the low level, so we're. in pass in our instances so create the constructors ctor tab twice and then we will create an ilogger and we will call it logger and a data access i, let's call it data access, okay, those are two parameters for a constructor and now we will have a ilogger here called underscore logger and we will have an eye data access called underscore data access so the reason for the underscore is because they are very similar to a private backing field for a property so we will treat them the same manner. way and name them in a very similar way, which is that they are being created externally, we don't need to initialize them and we won't change them in terms of reinitializing them, so we just say that the underscore logger is equal to the logger data and the underscore. access is equal to data access that way we take our parameters and put them in our class level variables, private variables, okay now here we don't need these two instances, instead we just use the script version low for those two instances, they have the same name. so that works fine, so now we have this class, the business logic class set up for the constructor to pass the two instances that he will need for this process data method that will allow us to pass the string.
Sorting dependencies are now here. they are passed instead of our dependency at the bottom, since the company depends on a company lock, so now we have to pass them in our constructor. We could create a factory to do it for us, but we know we want to use Auto fact, so let's do it. So we are here in the CS program, so in the references, right click and say majnu, get packages, search and type Auto FAC, the first one is just Autofac which has twelve point nine million downloads, you will probably download it, but this is the version of OTO that we are going to use there are other dependency injection tools Beauty Castle Windsor there are a few others, whatever you feel comfortable with is fine, they are all quite similar in terms of features and capabilities.
I have found that Autofac seems to be the simplest to use and still has all the power. I like it simple because I can remember it, so that's what we're going to use, so install it. I press finish. Okay, it ends, so now I'm fine and now. I'm going to start hooking up this CS program to use auto FAC. Now some people will insert the code right here for an automatic connection effect and the reason is because the first thing you want to do in your application is connect your container okay, that's where all the things that kind of factory was in the DV do the solid video for a dependency inversion principle, so we had that factory that created the instances after the container did it in Auto FAC and other dependency injections. systems now you have to create that or you should create it right away, that's the first thing you do, which is why a lot of people just put the code in static void main.
I prefer to keep it out of the code outside of here because that way I have a class that has only one job and that is to configure the container and it's very easy to read, it's very easy to understand and if you need to configure something, you know exactly where to go, so which I won't actually put it here. I create a new class in the console UI and let's call this class container configuration or make it public static. Well, we don't need to create an instance. You know, here we have a method called public static.
I contain the checkpoint where there are now two options. here using the system component model and using the auto effect here is a little tip it is not the system point component model ok it has an eye container which is not what we want we want the one with FAC automatic, okay, so it's an eyes container and we'll say configure it. says a method in this class is called configure and its whole job is to configure the container, so let's start designing it and then we'll talk about different parts to save our Constructor equals a new container constructor, okay, you have to compile. the container for us, the last thing it would do is return the dot build builder, so it was build it, ooh, well, builder dot build builds the container, so this is a container builder and it has a method that we will use called build and that build the container.
What the container is is a place to store the definitions thinking of it as a list of key-value pairs of all the different classes that we want to create instances. Right now it's empty, so it will return a list with nothing of what we're going to do. To change that, what we're doing here is after we set up the generator, we're going to tell it to register different pieces, so we're just going to say the point register type of the generator, and the types have a business logic. I have to take control of the point here to add a using statement for my demo library, so the business logic and the other test as business logic is fine, so what this does is the simplest version of a register and what does it say I'm going to register this class called business logic and whenever you and this like here, look for a visual business logic interface, return an instance of business logic, okay, so register the business logic and say respond whenever someone needs a piece of visual business logic, okay, it's pretty simple, I mean. a lot of the work most of the work is done behind the scenes, but essentially all we're saying is that when someone needs this, give them a new instance of this, okay, that's it, now doing this one by one might be a little long, okay?
If you have a lot of small classes but there are things you can do to automate this process, then I've already set up some automation prep work for us. I have put these two classes, the data access and the logger inside. the utilities folder is fine, now what we can do is say builder dot. Register assembly types. Okay, so record them, but that's just the types where I say assembly. I have to take control of the point here where we use reflection, since we're going to do point loading. so I'm going to load an assembly name from this is a new feature, by the way, and what it does is I can put any object name in here and it will basically return the string of that Abbott name because it could say this and that. would work but the benefit of doing it this way and saying the name of and object is that it is now strongly typed and it means I have it in intellisense and if I change the name of the demo library to something else and say change in all places where it is used, it will change this and know if the demo library is not there, look, you have a red squiggle, whereas if it's just a string, none of those things happen, okay, so name, I was something really powerful that they added recently, that's just amazing, okay, simple and yet powerful, okay, now I have what I say: load this assembly.
I have not finished. I'm going to make a link where T is equal to greater than T dot name space dot contains we can do the name again well, I don't do itthis. This seems like a lot of work essentially for what I had to begin with, which is I met a registrar that I accessed and called him, why would I have this disconnected type architecture on all this extra work that isn't much, but some creation of interfaces and then the container configuration that makes Autofac connect to it and call it and everything else? Why do that?
There are several reasons, okay, but there are a couple of important reasons. I think the most important one is that this here allows you to test your application in a way that you never could if you instantiated those classes here. So for example, let's say I want to test the process data method, so I create a unit test where I say call this process data method and then make sure the results are what we expect. What will happen. An entry will be recorded in my log. database wherever it is, it will load data from a database server and even scarier, it will save data to my sequel server wherever my database server is and that will log another entry on my log server , so now I have to go back and clean every time I run a unit test I have to remove those entries or I have to write the unit tasks in a way that I know which is the database and which is the record in the database and those deleted automatically, that's not a good thing especially Since what happens when I try to test this environment properly, I really shouldn't touch the data right, that won't work with half a touch of data, so now I'm creating a separate database which my unit tests point to and I try to keep it in sync with my production database, but that's a mess, you know, it causes a problem because of all these hard dependencies with this thing here.
Now I can test the business logic class very easily because I can pass in whatever I log and whatever I want. I make the access I want so I can mock this which means I create a dummy logger and a dummy data access class that way when I try the processed data method I can see if my dummy logger was called with this message and with this message I can see if the load data method was called and I can see if a save data method was called and with what information so I can verify that my method worked the correct way instead of without putting me in danger by touch any real data in any of the log files. or in the database, okay, so this here depends, the inversion principle allows me to not depend on specific instances, so I can pass different instances to test, that is very important, the other thing that this architecture allows us to do is which allows us to change the actual implementations in the future, so let's say we no longer want to have our current logging system implemented, no problem, we could simply change that in our container configuration, okay, maybe some business logic want to change everything, so instead we can still use the same business logic I, but instead we can call it better business logic and have that class implement this interface and then our code. it doesn't change one bit, we just change our business logic to be better business logic, okay, change it here in the registry and we're good to go, in fact, let's go ahead and do that, so we had this kind of business logic here.
Let's do this, let's create a new class in the demo library and we'll call it best business logic, let's make it public and we're going to implement the business logic interface I, which could push the checkpoint that we're going to do is from This is a demo I will copy and paste and make sure the constructor name is changed to better business logic. Add my using statement, so now it's exactly the same as the business logic, but let's make some changes, let's add some blank lines. I know this is really excellent. stuff here around the log statements, okay, so we added three blank lines now, let's just show you what was okay, nothing has changed right now, that's what a smashed city was, now let's go to the settings of our container and let's change this for the better. business logic no other system wide changes that's all we did run it again and voila your spacing is fine so with a change in one place I simply changed the way my application worked because it's not tightly coupled .
I have a dependency on Interfaces are not in implementations and I have my dependencies inverted so from top to bottom I pass this is what you are going to use instead of this is what you use so I passed better business logic now in place of the business logic when you request an Eye, business logic element now with that setting, I change my application, obviously, that's not something that you know is earth-shattering in itself just because it's a small change, but imagine if I used write to a sequel database and with that change I changed. to a Sequel Lite database or to my Sequel database or with that change I change to writing the text files, then the tournament tracking application that is in that C-Sharp application from start to finish, of course, I have that tournament tracking app. something similar to that, okay, but we're not actually going to do the injection in the pants this way, we can even more easily change which system I use, very simply, okay, make that change here and my entire application will be able to go from using text files for data storage to server sequel big difference a small tweak if your entire app is built this way, instead of your app being one big monolith it's a bunch of little pieces that can be swapped around when needed , so you want to update your application without a problem, one module at a time In a moment, change them and you are good to go, okay, you can update, you can move the systems, let's say you are on the sequel server and a company buys it and has than moving to Oracle, there is no problem with this system, you build the connection. to Oracle and then one day you go in here where it says Data Access, you change it from sequel server date access to Oracle data access and that's it, you know, in the blink of an eye, now It's in Oracle, now of course you had to write. the Oracle class, but that's a small piece, don't change it here, change it down here, change it here, change it here, you know what I mean, okay and I said, change it everywhere, change it in one place, so the dependency inversion principle is really powerful, but the dependency injection system allows us to do that in the Pantheon version very easily, so you are basically putting my manual factory with an automated one that is much better, has many more features and now , whenever I have a constructor and I need something. no problem so let's say in my data access I need a logger no problem I could just say ctor and give me an ilogger ok and now I can say logger equals plus time and now I can start logging the underscore recorder, the dot recorder, just Say logging data is fine, then it will say that the upload didn't have a record to upload to it and the same for Savi did fine, that's all.
I don't change anything else. I don't have to instantiate this somewhere to make sure they hit get the right one. I start this and now loading data logging loading data saving date process setup information logging saving data okay so those two logging statements are new because I just said Hi, any logger, no problem. Okay, this takes your system offline, and yet it's very easy to bring things in, so every time you see the new instance of something, that's when you think you know what you could probably do using dependency injection, there are some exceptions, it's okay, you'll still know. some things increase the pride of the most common, a new version would still be models, it knows the right data, so sometimes it can still be naked and does not use its two pens, the injection system for that, but otherwise, that's all.
Okay, so that's dependency injection again, it's different from dependency inversion. Dependency inversion is a principle. Dependency injection is how you make it work, one of the ways you make it work. Well, they're different, but they use the automatic effect, especially as you can see, it's really simple. you add your new reference still to the references, you create your container and that's where you just connect everything to connect what you're going to instantiate to your interface or you take me a bunch of them and do it once you've done that, then in Everywhere you need an instance of something, you just request it, okay, that's it.
The most important thing to keep in mind is that if you don't register something, okay, then I'm not registered, then the best business logic for my business. logic, if it starts, you will get an error and it gives us an error right here saying that an error occurred during activation of a particular record. See the exception between for more details. See some details of the exception between exception now that the constructors found with auto fat in thick core to activate sorry, reflection, yes, yada, and you keep reading and it says there is a problem with the business logic at the end, okay, so it basically says I can't find the business logic and the reason is because you didn't register. so make sure you register it if you do, you are good to go, your app starts, no problem.
I hope that made sense. I hope you understand much better how it depends on seeing the injection and realize that it is not a big deal. Okay, that's a big deal. from the perspective that it makes your life a lot easier and allows me to do a lot more things possible, but it's no big deal in terms of scaring and overwhelming everything else, you can do this, it's just a bit of setup, right? there and then it's about wiring up and having the interfaces for things that's it and then asking foreign builders okay now when you go into asp.net MVC or Web API or dotnet core these things will require additional configuration because at some point they have some kind of dependency injection already like that, for example in MVC the controllers are already being injected, so you have to connect Autofac and a little bit different configuration, but don't worry.
I'll cover that in a different video, but there are a lot of great tutorials out there as well. out there they cover it and it's really just a modification of how you do this. In fact, there are even nougat packages to help you, so they are not a big deal, but they are additional settings, but for wind forms for console applications. UPF, these things are already set up for you to be ready to do this, it's really okay, that being said, if you have any questions, please put them in the comments below. I read all the comments that are posted, if I can, all of them, so I may miss one, especially if you comment on a comment.
I may miss it, but I try really hard to read every comment and if you have any suggestions, please write them below. Let me know and I'll try to include it in the next video. make two more videos and okay, we'll do it until you understand it, so ask your questions, I'll try to answer them if possible and I'll try to put them in the next video if it makes sense, okay, also don't do it. Don't forget that in the description below there is a link to that blog post which has the start code and also the end code so you can try it yourself.
I always recommend rebuilding things yourself because it gives you the hands-on experience of doing it yourself. That's a lot better than just watching me do it because if you just watch me do it it's probably going to make sense or you're going to say yeah, yeah, I got it, I got it, but you actually come out, you have to wait, wait, how did I do that? Again, that's where the experience of writing it really helps, so try writing it yourself, create it yourself, make it work, create some different, really simple scenarios, but redo it two or three times, okay, so you understand how to do it. . then start installing your apps because this is really powerful.
I definitely recommend it for most applications. Okay, now we'll show it in a future video. I'm going to show mocking with unit tests so you can take this to the next level. is testing our app because of this disconnected architecture, so you'll definitely know about it because once you start mocking you'll want to know how to do two thought shots so you can keep up. That's all for this video. I hope you enjoy it. I appreciate it, give me a thumbs up if you enjoyed it too. I'll leave a comment below. Any questions or comments you have.
Thank you very much as always. I'm Tim Quarry.

If you have any copyright issue, please Contact