[SOUND] In this lecture, we're going to speak about one more very important concept that is actually used throughout AngularJS, and that is dependency injection. I'm sure by now you have seen this construct where we create the module that we're going to use in AngularJS, and we also create the controller with an associated function that is responsible for the functionality and kind of the glue code of that controller to the view. And you've seen the $scope that we pass into the controller's function, but where does this $scope come from, who instantiated? We've seen that when we do console.log on this $scope, it's a pretty complex object, so who instantiates that object? And the answer is that AngularJS instantiates this object for us, and the way we get that object as part of our controller is through something called dependency injection. So, dependency injection is yet another design pattern. We've seen one model view, ViewModel, and now there's another called dependency injection. So, it's a design pattern that implements something called inversion of control for resolving dependencies. So, inversion of controls is a construct or an approach for resolving dependencies. To understand what inversion of control means, let's take a look at how we usually go about architecting a couple of opponents in let's say a shopping cart. So the regular control will be, if we have a shopping cart, we can have a separate module called CardProcBank1, basically a card processing, credit card processing for Bank1 module and it has one method charge given the credit card number and the amount. And the reason we have a credit card for a particular bank is because, for that particular bank, we might have a particular URL that we have to contact a bank through and that particular can have its API. So we don't want to take all that code and stick it directly into the shopping cart because our shopping cart would be very much and very closely tight. Would have tight coupling with a particular bank API. We don't want to do that. So the way we would instantiate the cart processing, is we would create that cart processing module inside shopping cart. And then we'll just call charge, and call charge giving it the number and the amount. And clearly in this diagram, we see that the shopping cart module depends on the card processing module for bank #1. But what happens if tomorrow we decide that we don't like this bank, and we want to use a different bank because it has better prices for For credit card processing fees or something like that. So the way we would do that is, we would have to write a separate card processing bank 2 that also would have the same type of charge with the number and amount. And in that case it means our shopping cart code will have to slightly change And now when we create the instance of the credit card processing module, we would have to create it with obviously credit card processing for Bank2. And then as before, we would call that charge method passing at the number and amount. And here again you clearly see that the shopping cart again depends on this card processing for Bank2 module. But we have a huge problem here, we have to change the code inside the shopping cart which means we have tight coupling again. Just because we switched which bank we process our cards through we need to change the code inside the shopping cart? And how do you test the ShoppingCart? Let's say you only have a couple of simple methods, add to card and remove from card, in this scenario you wouldn't have to instantiate a whole credit card processing system just to see if your cart, your ShoopingCart Can place something into the right array and remove something from that array, keeping counts of total value of the shopping cart, total taxes, and etc. That would be insane. We can of course create a fake credit card. Processing module and instantiate that instead inside a shopping cart. But that would once again require us to change the code in the shopping cart. And having to temporarily change the code in the very function that we're trying to test seems like a really backwards and a bad idea. Who says we won't mess up something while changing the code for the test, and then putting it back the way it was? So what's the solution? The solution is Inversion of Control. And in this particular approach, our shopping cart functional module accepts a credit card processing module Is an argument and we still have that line where we call the charge method on that card processing module but if now is using the instance that we were passed from somewhere else. We get still have those separate modules but in this case, some Overall system is going to be the one who is going to instantiate that credit card processing. So in this case would instantiate the credit card processing for bank one. And the system is going to call the shopping card passing it the new instance of credit card processing for bank one. So in this scenario if we need a different bank for card processing the shopping cart code is left completely untouched it will not change. This is by the way why IoC or inversion of control Is sometimes jokingly called, don't call us, we'll call you. Because as you could see, the shopping cart no longer calls out to instantiate the card processing module, but instead we, the system, calls the shopping cart module providing the card processing instance to use inside of the shopping cart. So just to summarize. We learned yet another pattern called dependency injection for short it's called DI dependency injection which implements an approach called inversion of control and if you read things online or in other literature You'll see that inversion control is often times referred to as IoC, Inversion of Control. And in that approach, client gets called with the dependencies by some other system. And in our case, obviously That other system that surrounding ecosystem is angular js. And the whole point of it here is. Is the client is not responsible for istantiating the dependency that other code that it depends on.