Designing the Container API 0:00Welcome back. So, right now, we're storing dependencies within an array, but that's not overly flexible or portable. Let's create a new core app.php file, and this will be the most basic form of what we call a dependency injection container. But don't let that frighten you. It scared me for a number of years, in fact. It's not that complicated. This will just be a place to register or bind dependencies into them, just as a storage place, like a little registry. And then when we need to fetch those values, we can resolve them out of our container. Okay, so I'm going to create a couple methods, but before we do this, I don't know what it should be called. I don't know how this should feel to interact with. So when that's the case, here's what I recommend. Before you create the class, design how you will interact with it. So, for example, instead of all this, I want to do something like this. App, bind, we're going to call the key config, and we're going to fetch our configuration array, like we did down here.So, for example, instead of all this, I want to do something like this. App, bind, we're going to call the key config, and we're going to fetch our configuration array, like we did down here. So think of it like this. Find the configuration array. We got that. And we will take that array and store it within our container, and we're going to associate it with a key named config. So now, if I ever want to grab this configuration array, all I want to do is something like this. App, and it could be resolve if we want. It could be something as simple as get. So if we did this, ultimately, I want that to return, once again, the configuration array. Okay, so do you see how this works? It's just a container, literally a box, where you take things, you throw them into that box, and you assign a label to them. Just like this. Throw this array of stuff into the box, and then put a config label on it. And then later, if I ever want to get that stuff out of the box, I just look for the config label, and I save it.Just like this. Throw this array of stuff into the box, and then put a config label on it. And then later, if I ever want to get that stuff out of the box, I just look for the config label, and I save it. That's all we're doing here. Okay, so that means we can get rid of this, and then what about this one? Well, I could just say app, bind, database, and make that equal to a new instance of our query builder. And we can get rid of that. But now, what about down here? Okay, well, let's just grab config out of the container, like so. Or you could even do something like this, where you could say config equals that, and then you could continue doing something like this. Any of those works, but we'll keep it like this. Implementing Bind/Get Methods 2:17Or you could even do something like this, where you could say config equals that, and then you could continue doing something like this. Any of those works, but we'll keep it like this. Okay, so now that I understand my API a bit more, we're going to set this up. We had a bind method, where we gave it a key and a value. And then we also had a get method, where we give it the key. Okay, so why don't we store, and we'll call this maybe like registry, or items, or keys, or anything you want here. It doesn't matter at all. And all we're going to do is each time we bind into our application container, we're just going to store it within this array. But now, if I want to grab this value, we have a problem here. We haven't talked about statics too much, but when you are within a static, you're not dealing with an instance of the object.But now, if I want to grab this value, we have a problem here. We haven't talked about statics too much, but when you are within a static, you're not dealing with an instance of the object. So that means I can't do things like this, because I don't have an instance. It's a static method. So why don't we do this? Let's make registry static as well, and then that way I could say static registry key equals value. Okay, so think about it. If you were to say at bind config, and then provide this array, ultimately, we will push to this array, and it'll look like this. Config, and then the array that we had stored here. Next, if we did it again for database, well, we call this, we push to the array, and then we'll have something like this.Config, and then the array that we had stored here. Next, if we did it again for database, well, we call this, we push to the array, and then we'll have something like this. And then that would be our query builder instance. That's all we're doing here. Very simple stuff. So now if we want to fetch a value, we could just say return static registry, and then give me the key. And this would be fine. What you might want to do, though, is check to see if the registry contains the array. So you could do something like this. If array key exists, and we'll give it the key, and then the registry, then what do we want to do? Testing and Fixing Autoloading 4:03So you could do something like this. If array key exists, and we'll give it the key, and then the registry, then what do we want to do? Well, maybe we check to see if it doesn't exist. And if so, maybe we throw an exception. No key is bound in the container. Just to give you a bit of feedback there. Okay, and that's it. Like I said, very, very simple here. So if we come back to our bootstrap file, why don't we die, and then var dump app get config, and see what we get. Refresh, and we get class app not found.So if we come back to our bootstrap file, why don't we die, and then var dump app get config, and see what we get. Refresh, and we get class app not found. So what's the problem? Well, obviously, it can't autoload the new app file that we created right here. Well, we learned a little bit about Composer in the last episode. So let's take a look at that class map, and you'll see here's all the items. But we don't see app. And that's because this isn't dynamic. We have to tell it to hunt through all the files and build up this array. So we can do that like this.We have to tell it to hunt through all the files and build up this array. So we can do that like this. Composer, dump your autoload file. So re-query everything, and then dump it into that file we just looked at. So now if I switch back, you'll see a handful of new things. And specifically, there's our app file. So just remember, if you are using a class map for Composer, whenever you add new files, you need to rerun that command. Okay, so back to Chrome, give it a refresh, and there we go. And remember, you can bind anything into this container. So I could say app bind foo bar into the container.And remember, you can bind anything into this container. So I could say app bind foo bar into the container. And then if I want to fetch that, we should get bar. And we do. Once again, we refer to this as a dependency injection container. It can get quite a bit more complicated than this, but for our needs for this little project, it's more than enough. So now that we've cleaned things up a good bit, our bootstrap file is way cleaner. We're not requiring files. We don't have an app array. We don't have anything like that. Updating App References 6:04We don't have an app array. We don't have anything like that. All we have to do is update a couple of references. For example, back to the homepage, and we can see that in our index controller, it can't find that app variable anymore. And that's because we deleted it. So let's go in here. And yep, no more. It doesn't exist. We can use our DI container. I can say app get database, and then select star.We can use our DI container. I can say app get database, and then select star. Refresh, and there we go. Let's update a couple others. Contact looks good. Here, same thing. App, get database. And are we good for everything else? I think so. Okay, so good job. Planning Dedicated Controllers 6:45I think so. Okay, so good job. In the next episode, well, we're talking about classes more, but our controllers are still just simple files here. I want to switch over to a dedicated controller, because as you can imagine, this could get really messy really fast.