The Laravel Podcast

The Service Container, with Christoph Rumpel

Episode Summary

You may not know it, but the service container — also known as the container, the IOC container, the DI container, or just "the application" — is that the core of every Laravel application. It's the glue that holds it all together! In this episode, author of Laravel Core Adventures Christoph Rumpel helps us dig deeply into what the container is and why it's good for you to know about it.

Episode Notes

 

Episode Sponsorship

Transcription sponsored by Larajobs

Editing sponsored by Tighten

Episode Transcription

Matt Stauffer:
Welcome back to the Laravel Podcast season four. Today we're talking to Christoph Rumpel about the container, which is the glue that holds your entire level up together, even if you don't know it. Stay tuned. All right. Welcome back to Laravel Podcast, season four, where every single episode is about a specific topic, and today we're talking about the container, which I think if you've been using Laravel for a while, you totally understand why this is a really important topic. But if you haven't, you might not understand what it is or how important it is, which is why I've invited my friend, my guest here today.

Matt Stauffer:
So my friend has a name, which I will do my best to not mangle, but I know I will a little bit, Christoph Rumpel. Whatever. If you're American, you probably say is Rumpel. He'll say it himself. It'll actually be correct. So he is a freelance programmer who does Laravel and PHP. He's got some video courses, books. But he also has something called Laravel Core Adventures, in which he dove into all of the core and the internals of how Laravel works, which is why I thought he'd be a really great fit for talking about the container, because he's really dug into how the glue is, what the glue is that's putting all of the pieces together in Laravel.

Matt Stauffer:
It's a free video series. So you can go check it out. We'll put it in the show notes and everything like that. But I'm going to stop talking, and I'm going to say, Christoph, can you say your name really? But also, when you meet somebody at the grocery store or whatever it is during coronavirus COVID, how do you introduce yourself? How do you talk about what you do?

Christoph Rumpel:
Yeah. Hello, everybody. Thanks, Matt for having me. So you were pretty close. It's Christoph Rumpel.

Matt Stauffer:
Almost done.

Christoph Rumpel:
Yeah. But everybody who's English speaking just says Rumpel, and I'm fine with that as well. So that's okay. If I meet someone a grocery store, I would probably say something like I'm a programmer, and I build websites. So that's the ease introduction, and then yeah, it gets sometimes awkward because people say, "Oh yeah, can you do my website? Or can you do my company website or personal website?" Then I'm like, "Yeah, I could. But actually, that's not what I normally do." So I wouldn't do that, and they're confused. Yeah. You said you do websites. So why you can't do my website?

Matt Stauffer:
Why mine. Yeah.

Christoph Rumpel:
Then it's difficult to explain.

Matt Stauffer:
Yep. So if you talk to a programmer, how do you tell a programmer what you do if they understand the context a little better?

Christoph Rumpel:
Yeah. So I'm having my own one-man company. So that's what I tell them. I'm a freelancer. I do mostly PHP and Laravel. So I'm working now with Laravel since version four. So quite a long time. I heard you mentioning, I think it was in one of your talks or somewhere that also you were following or Jeffrey, and he mentioned Laravel. Yeah, it was the same for me back then. Was it called, Nettuts, the blog, and he mentioned Laravel, and I was like, "Okay, what's that?" Yeah. Since then I'm using Laravel. So it's been quite a time. Yeah. That's what I tell people. I do PHP. I do Laravel. I do freelancing, consulting, and then also have my own products like the video course that you mentioned, Laravel Core Adventure. I have to say it's not completely free. So this was-

Matt Stauffer:
Oops, my bad.

Christoph Rumpel:
... at the beginning of this course. It changed a little bit. So there are a lot of videos which are now free, and some, you have to buy a program, and then you can see all of the videos, and they also wrote a book about chatbots, which is a little bit outdated, but yeah, try to have my own little products and yet try to build stuff myself and sell that as well next to freelancing and consulting.

Matt Stauffer:
Got it.

Christoph Rumpel:
That's basically what I do, and yeah, basically just a backend developer working with PHP and Laravel.

Matt Stauffer:
Got it. The reason I actually was thinking it was free is because you have this wonderful article called How I Built Laravel Core Adventures, which I recommend everybody to check out because it's a step-by-step walkthrough what it took to build a landing page and to brand Laravel Core Adventures and what the tech stack was and everything like that. At that point, it was entirely free. But if y'all are interested at all, either building your own product or just seeing what goes into it, it's really, really, really fascinating. He's talking about using canvas to build these animations and all the research he did. So I think it was a really, really wonderful. Again, I'll link that in the show notes as well. It's a wonderful article, so-

Christoph Rumpel:
Yeah. Thank you. I often like about the things that I do, because yeah, I'm not super smart and can explain all the super cool things that nobody knows, but what I learned last year is that a lot of people are interested in real-world things, so what people do, and even if it's just a little website that it build, a little product. Also, with my website, I have an article about how I built my website, which is just Laravel application, which is just a block, but still, there are a few things that, yeah, people are interested in how I convert maybe marked on files to HTML and all those little things.

Christoph Rumpel:
If you pack that together and give people real-world examples, and they really appreciate that. For you, maybe it doesn't sound like it's super interested, but it's still is interesting to a lot of people even if you don't think so. Yeah. That's why I always like to share what I do because yeah, that's also how I learned a lot from other people.

Matt Stauffer:
Yeah. One of the things that I love is that I learn much from people on videos by watching it, but I can't always watch videos, and I love that you took the work to put this long form content in because there's also some stuff that it's a lot easier for me to discover, even by skimming a post like this. Even if someone doesn't have time to read the whole thing, even by skimming, because you'll see little animations and go, "Wait, wait. What's going on there? So I love that."

Christoph Rumpel:
Cool.

Matt Stauffer:
All right. So at the beginning of these, I want to talk about who you are. Now, I want to talk about your topic. This is probably one of the more complicated ones to do this, but if you were to describe Laravel's container, and just so everyone knows, we're talking about the inversion container or the dependency injection container or the application container. We'll talk about all those in a second. But if you were to describe that thing to a five-year-old, how would you do it?

Christoph Rumpel:
Yeah. So of course, I've watched most of the other episodes, and I know of this part of the episodes. So we're thinking about this now for weeks. Yeah. Because yeah, as you mentioned, the service container, for me, it was one of the most difficult things about Lenovo to understand, and it's quite complex and all those crazy words and terminology around it, and yeah, I thought, "How could I, yeah, describe this to a five-year-old?" I'm very interested in what you say about this one. I think it's quite good. So let's see-

Matt Stauffer:
Good. Let's see.

Christoph Rumpel:
... how it goes. So let's say a little Matt, five-year-old, has a birthday party. You have some wishes for your birthday party. You want maybe a cake, you want some lemonade, you want balloons, you want the magician, and you have to party with your friends, and your photos at home, and your father is taking care of those things. Of course, he doesn't know all the details about what you really like because yeah, your mother maybe knows a little bit more about you, and she wrote some notes about it. So when your dad wants to get a magician, yeah, your mother wrote a note about, "Yeah. Matt likes playing with cards, a magician who can do hat tricks would be cool.

Christoph Rumpel:
I know this one. So maybe you ask this one or maybe about the lemonade. Matt really likes lemonade, and you should use 10 lemons and maybe a little bit of mint and not too much sugar because he doesn't like that or doesn't need that. Yeah, the mother wrote all the notes for the father to do these things. Now, in this example, your father is the surface container. So your father is taking your request from little Matt for your birthday party, and he can give you all the things that you want, but there's also your mother helping out. What are all the little details that your father needs to do in order to give you the things that you need personalized for your use case? So your father would be at the service container, and your mother would be the service provider.

Matt Stauffer:
Yeah, that's really interesting because I've never thought of the container as a person in this scenario before. I was thinking of it as an inanimate object. So I'm thinking through that. So I'm little Matt. It's my birthday party, and I want to ask for things. So I'm the consumer. I'm the programmer maybe writing some Laravel applications. I reach up to the container and I say, "Hey, container. Can I have my cake? Can I have my lemonade? Can I have my whatever?" The container is not actually the one that necessarily knows how to fulfill those things. It just has a tooling built in that is, when asked for thing, reach for the things that have taught me how to do that and then follow the instructions and then hand it back.

Matt Stauffer:
Then there are various things that have potentially taught the container, how do you fulfill that thing when time comes? I love that. So because my brain always works in. I gave a talk about the container ages ago, where I imagine it being like cubbies, like a big storage shelf. Similarly, if instead of a dad, let's say it were a cubby where both the dad and the mom had contributed, right? The dad knows about certain things that the kid wants to do. The mom knows other things the kid wants to do, and maybe for some reason, a third party has to be the person throwing the party, right? Neither dad nor mom, every single time that third party is going, "Oh well, dad really knows that little Matt likes this and reaches into a cubby that happened to be filled by dad, dad is one service provider. Mom's another service provider." Yeah. I think that's really cool. Man, nice work. Yeah.

Christoph Rumpel:
Yeah. You have to think about it a little. Yeah. I think it's cool because, yeah, it gives you already some insights about the base concerts. You wish for some things. You have a wishlist for things that you need, and then there's someone who gives this for you, and then there's also somewhere some information about how this thing that you need is build up or what are the tasks that you need in order to give the right things back to the person who asks for it.

Matt Stauffer:
Yeah. So that's fantastic. Let's try and translate that now into a little bit more technical of an answer. So if I am a Laravel programmer, and I'm building my first app, what is the service container to me? Where do I actually kind of interact with it on my first time?

Christoph Rumpel:
Yeah. So that's a good one zone. The service container is quite a complex topic because of a few reasons. So first we have the terminology, which is yeah, could be quite difficult. You have the service provider. You have to service container. You have dependency, injection container. You have inversion of control. You have binding resolving, and all the things are not so easy to understand, especially also if you're not speaking English because when I learned English, so binding and resolving and not things that. I learned just from speaking to people and for people that don't speak English, these words makes it a little bit more complex because yeah, what do you mean?

Christoph Rumpel:
Yeah. This is why this topic is a little bit difficult to understand. But what I like to do is that's also what I wrote about and also what I did in my course is I had problems understanding because of a few reasons to service container because of the terminology, because a lot of things are in the back. You don't know what's happening. The framework does a lot of the things behind what you see. This is why I like to explain the service container more from the user view. So when does the user encounter the service container? When can the user was coding? So I'm speaking about the one who's developing, the programmer can make use of the service container. This helps the user better to understand what the container's for and then also better understands how the framework itself uses the container for all the things that the framework needs in order to, like you said, clue everything together.

Christoph Rumpel:
So I like to think of this example where you have a class like an order class from one to maybe store in order or in your application that happens in order. You also want to send out an email, now that the orders store. So in your class, you need to send out this email, and now we have, yeah, you can call it a dependency. As mentioned, dependency is also something that's very unconnected to the topic. The dependency just means basically that we are using a different class or a different service or a different feature of the application of the framework that we want to use now in a different class. So now, the mailers to example that we want to use is not a dependency of our order class.

Christoph Rumpel:
Okay. Now, there are a few things how we can text me this. So the easiest way is just to create a new instance of a mailer in our auto class. So let's say a new mailer, that's it, and then we can send that email. So this will work. No problems about this. But yeah. This could get a little bit more tricky because spinning up a new instance, creating a new instance is not always just new incense and that's it. So maybe your dependency has different dependencies as well, and then your dependency has dependencies, and then maybe you need to load some configuration. You need to check this or that, and then spinning up this in standards like five or 10 lines of code, and then it gets a little bit complicated.

Christoph Rumpel:
So the first thing why we would want to change this is because now in order class, we have a little bit of a mess. We now have 10 lines of code regarding the mailer, which is not the responsibility of our order class, and this is one reasons we would want to change this. Also, if we to use the mailer now in a different class, let's say in a controller or maybe in the user class, then we would write those 10 lines of code again. Then yeah, if you need to change something, you need to change at different places, and this is when we talk about separations of concerns because yeah, we want to keep those knowledge. We don't want to have the knowledge about the mailer in our order class, just because it's much easier because when we go to the order class, we won't just want to know what the order does, and we don't want to know about the mailer class, because then we would go in a different class and check this out somewhere else.

Christoph Rumpel:
So separation of concerns, cleaning up is a reasons why we would want to change this. One way we can do this is by defining at one place how our mailer is set up. So all the things that we need in order to create a new instance of a mailer, we define it just one place, and then inside our order, we would just get this instance. So this way, we can make changes easily and we don't have this mess in our order. This is something that the service container can help us.

Christoph Rumpel:
So what we can do is we can define at one place how our mailer is set up and then insert our order class. We can make use of the container and just get back the mailer instance, already created instant that we can use immediately. Now, this is much easier to understand in our order class what's happening is, and we don't care about the mailer. So that's something we don't need to see here. The way we can do this, the way we can interact with the container, so there are a few ways we can do this. We can directly call the container. So this means inside our order class, we can make use of global app helper, for example.

Christoph Rumpel:
Then we have different methods on the application instance that suppose the app helper is returning, we can ask for a specific instance by a key. So that's also an interesting concept to understand. When we talk about the container, you can basically see it as an array with key and values. Key is just a shortcut on how to get to the value, and the value contains all information. So in our case, we would ask the container for the key. So we could call it like mailer, and then this is all that the container needs in order to create this instance.

Christoph Rumpel:
Then there's one place where we have defined how the mailer instance is created, and this is something that we'll talk a little bit later as well, but for now, I think it's interesting. We asked the container for something by the key, and we get back this instance. So this is one way of how we could interact with a dependency in our order class. A different way we could do is by using dependency and checks. So there's always, always interesting if we have different dependencies. So like before, we're using the order, and now the mailer would be a dependency of order class, then we're talking about a dependency, and it makes sense to inject it via the constructor, for example, because then it's much more separated and we can define on how we pass this.

Christoph Rumpel:
But now if we talk about the container, there are few places in Laravel that a container helps us with injecting through the service container. So for example, inside a controller, I can just type in the class, and then the container checks in the background if it has some knowledge about this class and can give us back this instance. So now, with the same example, for example, we're now in the order controller, and we type in the constructor, the mailer method or the mailer class. Then in the back, Laravel checks this, sees, okay, we want to use this mailer class here and checks if I have any information about it, and then it finds the place where we have defined those 10 lines of code how to set it up, and then it would give us back the application instance. So that's very interesting to understand, because we use this quite a lot in Laravel.

Christoph Rumpel:
We're typing in a class, so for example, in the constructor of our order controller, and normally, you would pass this dependency yourself if we're just working with plain PHP classes. But since we don't create the controller class ourselves, we are not responsible, although we can just pass anything in there. But Laravel is smart enough to check this through reflection, which is a PHP feature. Okay. The user wants here the mailer class. Let me see if I have some information about this and then gives us back this instance. So this would be the second way of how we could interact with the service container in order to get the mailer for our order class.

Christoph Rumpel:
This method that we were not talking about is also connected to alter resolve, and which is not a topic, but maybe I'll give you some time for some questions or some...because it gets a little bit complicated if you talk about all the things at once.

Matt Stauffer:
Yeah, for sure. So that's a ton of really great information you threw together in there, and I'm going to kind of walk through a couple of different pieces so we can make sure we kind of clarify what each of them are. So I love how much you get in there. So we're going to step back for just a second and talk about a few fundamental concepts for anybody who's not familiar. If you don't feel like you were able to follow what just happened, we're going to work through these concepts and maybe go back and listen through that again because it'll make more sense.

Matt Stauffer:
So dependency injection is the idea that when you have your class that depends on something else, instead of doing all the work like Christoph was talking about inside of your class, to get that thing set up, remember how we talked about the mailer might have four dependencies, and each of those dependencies might have dependencies, and some of those dependencies might need configuration items passed in, and it could just get super overwhelming, right?

Matt Stauffer:
So instead of doing that all in the order, you pass it in from the outside. So the order class defines to the outside world, in order to exist, which is what the constructor is for, if you type hint something in your constructor, by that, we mean the constructor method has a parameter that needs to be passed to it, type-hinted mailer. That means in order for an order class to even exist, you must get me a mailer. So you're sending a message to the outside world, without a mailer, you don't get an order, right?

Matt Stauffer:
So that's that's dependency injection is instead of knowing something up inside of the class, you define that it must be passed in from the outside. If you could do dependency injection and still do all the hard work yourself of instantiating that thing right before you instantiate the order and then just pass it in. So dependency injection has nothing to do with the Laravel container at its core, except the Laravel container makes it easier. So simplest thing is you build this order class. Your constructor has a type-hinted parameter that is mailer. So it says every single time you make an order, you make the mailer.

Matt Stauffer:
First thing you do in vanilla PHP world is you just create the mailer, configure it how you want, but then you have to do all that same work still in your control or whatever, right? Then you pass it into your order. So what Christoph was saying is, but there's certain ways in which we can set it up, such that the container itself does that work for us, of sniffing out what those type-hinted parameters are for your constructor and saying, "Hey, you know what, I'm going to handle it, take the responsibility for giving you the mailer or whatever. I'm going to learn the knowledge of how to inject that thing in for you, and so you don't have to do it yourself."

Matt Stauffer:
So the simplest way to look at it is you can instantiate an order class yourself in such a way where you can ask the container to inject whatever it smells, using reflection, whatever it smells and your constructor, or you can also use an example of a controller, just like Christoph said, because every controller you have, nobody ever goes new controller in their code, right? So that's a wonderful example of what happens when you type-hint something, and Laravel already, based on the way it's set up, takes the responsibility of sniffing out those type hints and injects it for you.

Matt Stauffer:
The cool thing is you could do that same thing with the order class if you wanted, but that's a little bit ahead of where we are right now. So just baseline, that's what dependency injection is. Like Christoph said, whenever you got to dependency, you got to get it in there somehow. You're either going to new it up in line, or you're going to pass it in from the outside. The two ways to pass it in from the outside are one, dependency injection, like you said, or two, you can actually directly in line in your code just say, "Hey container, can you give me one of these." Which is where he was talking to the global app helper, and you just use the app helper to reference the thing.

Matt Stauffer:
There's one other thing I wanted to clarify there, which is that he mentioned the fact that you could use the shortcut, and you could say, "Hey app, give me an instance of mailer." M-A-I-L-E-R. That's it. So that's a shortcut, but baseline, before you even learn about shortcuts in the container, the container itself inherently knows how to spin things up most importantly by their fully qualified class name. There's FQCN. That is literally app/services/mailer::class, right? Let's just the string app services mailer. So if you were to go to the container and just say, "Hey, give me one of these apps/services/mailer," it knows to just try and go new that thing up.

Matt Stauffer:
If it can't new it up, we'll talk in a second about what we do in that circumstance. So when he's talking about using that little shortcut, M-A-I-L-E-R, that's just an alias on top of the core functionality, which is just to map, even if he's talking about keys and values, right? I love the idea of container. It's just a whole bunch. It's an array of keys and values. The key at its core is actually just the class name, and then the value is an instance of a class. Then there's all sorts of stuff we can do on top of that with aliases right.

Matt Stauffer:
Now, technically, it's in inverted in the way Laravel sets up its own classes. So if you're an old-head Laravel people person, yes, I understand. But for newcomers in general, the key is the class name, the value as an instance of the class. So I'm hoping that right there. If anybody was having any trouble following what he was saying, I think it's because not everybody understands how dependency injection works. So Christoph, you've given us a lot of really wonderful examples about what it looks like day-to-day to use it.

Matt Stauffer:
So you mentioned the fact that building a class and doing constructor injection or using the app helper is one common way. We can type in things in the controller method signatures, and the container will reach in and take a look at it. I think maybe the next most appropriate thing to talk about would be, what does it look like to teach the container, how to resolve something? What things can it resolve without being taught, and what things does it need to be taught, and how do we teach it?

Christoph Rumpel:
Yeah. Good point. I also wanted to mention again, as you said, if this already is a little bit too complex or difficult for you to follow, that's totally okay. It took me some years to understand most of those concepts. So just what should, again, we'll also mention some other resources, but you can go through and don't be afraid of death. So okay. So how do we tell the container about how to create an instance like for the mailer that we've mentioned before?

Christoph Rumpel:
So therefore we have service providers, and service provider is a class where we define, yeah, how to create a specific instance or feature. It's good to talk about, yeah, how Laravel itself is, yeah, created. So Laravel provides a lot of features. We have meeting system, we have routing, we have authentication and so on and so on. Laravel has a provider for each of those features, and this just tells the container how to create those instances.

Christoph Rumpel:
Again, it's not as easy as just creating a new instance new up. If you check some of the service providers from Laravel itself, you will see, okay, there's a lot of things happening here because it gets quite complicated if you have, yeah, dependencies and deal with configurations and stuff like that. Yeah. Service provider is a class where you define how an instance is being created. So in the service provider, you have two methods, the register method and the boot method, and the register method is where you will define this. So in there, what's called the app instance that we have inside the service provider because it extends a base class, and here we have access to the application, and Laravel application is the same as the service container or the application instance, you could say.

Christoph Rumpel:
Here, we would say, "Okay. We want to bind something now to the container." Buying just means we are going to save this information now inside the container. So for our mailer example, we would say, "Okay, we want to bind it to a specific key." And then the second argument would be a closure. This is just a function where you find all those lines that we were talking before how to create this instance and in this functions closure, we are going to return the instance. Now, inside our service container, we have inside our array we have now our key, and then on the other side, we have some information about the data.

Christoph Rumpel:
One of the information is the closure that we have defined. So the next time we're asking the container for the mailer, then the service container checks, okay, yeah. I see I have this key. I have some information about it. I'm now going to call this closure and run the code inside, and this will give us back the instance that we needed.

Matt Stauffer:
Yeah, that's great. So that's a perfect example for our mailer in which there was, and you said, let's talk about 10 to 15 lines of code to figure out how to set up a mailer, because maybe the mailer has two dependencies and all that kind of stuff. So a lot of that would belong in the closure. But one of the interesting things I think about the container is... Well, there's two interesting things. One of them is if you have something that doesn't have any dependencies, you don't have to even define it, right? You don't have to bind it anywhere. You can just say, "Hey, container. Give me an instance of this."

Matt Stauffer:
If you ever do that, it'll just go, blah, blah, blah equals new class. Right? As long as the container can do that, just run new class, it'll just do it for you. So you can ask the container for things that you've never bound when you're in a situation where you do need this kind of set up you're talking about, that's when you have to do it. But even then, let's imagine that we had those 10 or 15 lines of code that are defining the container how to instantiate a mailer. Well, probably at least half of those lines of code are not about how to define a mailer, but they're about how to define a logger, right? Maybe every single time it sends mail, it also wants to log that it sent the mail to your local logs.

Matt Stauffer:
So half of your defining a mailer is injecting stuff in the mailer. But half of it is defining a logger. Well, you don't actually need to put that in that closure because you're gonna make a separate closure somewhere else that says, "If somebody asks for a logger, here's how to set up a logger." Right? So if you've got one service provider that teaches the container, here's how to instantiate a logger, and it might take configuration items like, what is the logger that we have set up for this app and what is its path that it needs to log to whatever.

Matt Stauffer:
You've now taught the container how to instantiate the logger class so that when you go and define to the container how to instantiate the mailer class, you don't have to do that work again. You just say, "Hey, when you're instantiating a mailer class, ask that container for a logger." It knows it'll go, well, somewhere else we've defined a closure about how to instantiate a logger, and it just throws it in there for you. So that's why he was talking about, "You have an instance of the container available to you when you're binding things into the container."

Matt Stauffer:
So it's like the self-building thing, where every time you teach the container, how to resolve something, the next thing that you define is going to be simpler because it now just gets to say, "Well, oh, I don't know how to instantiate." The mailer can literally just say in it's closure, "I don't know how to instantiate a logger. Just go ask the container for it." Even though you're talking to the container. So you're building these smaller and smaller and simpler steps that just teach a little bit of it. So in the end, like you said, in your service provider, you've defined how to instantiate a mailer. So as a result, when we asked the service container for a mailer, just like you said, the service container doesn't know, but it goes and asks those notes, "How was I supposed to make a mailer again?" It's like the parent who's around more giving notes to the parent who's around less, whichever parent that is. So that's really good note there. I like that.

Christoph Rumpel:
Yeah. I also wanted to come back just for a minute to where you said, "Okay. We can also ask the container for things where the container doesn't have information about it." This, we're calling, I think it's called alter barring, alter resolving, so different words for that. But I think that's interesting to talk a little bit more about it. Because we can ask the container for a class for something that is not defined in the container. So there's no service provider for it, and now the service container checks, "Okay. I don't have information about it. What can I do with it?" Then as you said, the container tries to create this instance himself or herself or however you will say that.

Matt Stauffer:
Itself.

Christoph Rumpel:
Itself. Yeah. This could be just, yeah, creating a new instance, just new and then the class, and maybe this works, then it would give us this back. But if we have some dependencies, then the container checks, "Okay, what are the dependencies? Can I create the dependencies myself?" Now, this would also work if the dependencies only have dependencies that the container can create. So your dependencies can have dependencies, can have dependencies all the way down, and it would still work as long as there are things that the container can create themself.

Christoph Rumpel:
So if you have an argument for a specific string or something that is not type hinted then, yeah, then the container doesn't know how to create this instance, and this is when it will flow and think of an exception to tell you, "Okay, this is not something that I can create myself. I need help with that." But it's pretty cool when I think about it. You ask the container for something, and it tries to create it yourself, and this is pretty cool how this works.

Matt Stauffer:
I really appreciate what you said there, because if you missed it, what I had said was if you try to new something up that doesn't have any dependencies or it doesn't require anything else, well, yeah, the container can new it up. But what Christoph clarified is that's not entirely true. It also can new it up as long as it knows how to new up its dependencies and dependency those dependencies. So that is either because they've been bound or because maybe all the dependencies of the class that you're trying to instantiate don't require any custom configuration or special things.

Matt Stauffer:
So basically, if all of your dependencies of your class can be newed up just by doing new blah, blah, blah, blah, blah, or maybe all the dependencies dependencies can new it up, if there's nothing down that whole kind of dependency tree that needs anything custom, you could literally just throw those classes in a brand new Laravel instance with no service providers whatsoever, ask the container for an instant thing. It's going to go the whole way down the dependency tree. It knew each of them up, passed them into each other, and then you're good to go without doing any custom work, and that's auto wiring, like you're talking about.

Matt Stauffer:
There are some containers in the PHP world in the past that didn't do auto wiring. So on day one, even if it could be smart enough to do that, they made it so you'd still have to bind them. Laravel is very intentional in saying, "Hey, look, if I can do the work, I'm not going to make you do the work." So service providers are only about teaching the container how to do the things that it is completely incapable of doing because it's not inferable, right? It must be defined at some points. That's a really great point there.

Christoph Rumpel:
Yeah. Right.

Matt Stauffer:
So one of the first things we usually go to after this point is to ask questions like, when's the last time you used this system? I think that I'd like for us to hold off on some of the more terminology and talk a little bit more practically still for a little bit. So we talked about the fact that intentionally resolving dependencies of custom PHP classes, we've created is one common use case. We also talked about dependency injection in our controllers as another common use case. Are there other places where you think it's really helpful for us to understand that the container is operating on a day-to-day basis in the Laravel apps that might help us better take use of it?

Christoph Rumpel:
Yeah. I think it's always important to think of packages when we talk about the container. So every time we use a package, we need to provide those features from those package also in the application, and every package has a service provider of a Laravel package and it just tells the container about the things that we can use. This could be defining some routes, defining some comments that we want to use in our application. It's like an entry point for your application to a package. Every time you use a package or you create a package, you will also need the service provider, and here you have, yeah, the place to add those functionalities that we then can use inside the application.

Christoph Rumpel:
So there's one also thing that I think is really good to understand, because it also tells us about again, how Laravel works itself. So basically, Laravel itself, yeah, is built up off a lot of packages, and all those packages have service providers as well, and then what it didn't talk about it all the Laravel service providers in order to boot up the framework. So now the loads, all those service providers in order to have those features that the framework needs itself, it's very interesting if you check out the index PHP file of the frameworks or the main entry point of application, inside there, we are creating the first application instance. So I think that's a third of the second line of code that's happening there, and from there on, we have the service container and can use it.

Christoph Rumpel:
Very early here, we are also binding the base service providers, Laravel, which is the route service provider, the Lux service provider and the events service provider. So these are three features in Laravel that the framework itself needs very early. So this is why these are the first service providers that are being loaded so that it can use the framework itself. Then later, I think it's at a kernal or somewhere also. All the rest of the service providers are being noted. When you check out your config at the PHP file here, we have a place where all those service providers are listed, and you probably, if you have used packages before, you went to this file and edit the service provider from the package down.

Christoph Rumpel:
We don't have to use this anymore because I think this now works automatically, but still it's a good idea to see, okay, all those features Laravel needs themselves, Laravel needs a lot of service providers, and then it can use them properly. Because of course, we can just create a class or a package could create a class, and we can easily use it everywhere, because sense of composer, we know of all the classes that we can use, but there's much more information to creating such an instance, and this is why we have all those service providers.

Matt Stauffer:
I love that note because... So if you've ever worked with a package that is primarily targeted at a PHP in general, not primarily targeted Laravel, you'll very often look at the README, and the README will have instructions about how to set this up. Some things are very simple. The README has got a couple of steps. But often, especially if you're dealing with code where there's a lot of complexity going on there, whether it's because it's a super abstracted system, or maybe you're dealing with like an Amazon SDK, where there's seven different classes that need to be injected to each other. The README telling you how to use this thing for the first time can often have 10 to 15 to 20 lines of code of how to split up this package.

Matt Stauffer:
When you see that they also have an optional thing that they often call it a Laravel bridge, what they mean is if you're not using Laravel, somewhere in your code, you're probably going to need to write in this 20 to 25 lines of code. If you are using Laravel, the service provider that we've offered with this will run those 20 to 25 lines of code for you in a way that it automatically taps correctly in your configuration settings. So there's doing two things. One is that they're making it such that if there's configuration settings, that they know they'll need, that they can pull out of the Laravel configuration, then they do. But the second benefit is that you don't have to run those 20 to 25 lines of code every time you need it. They're taking the responsibility for you of defining to the container of how to get an instance of their package.

Matt Stauffer:
So it's just like, we're talking about here. The third-party packages are defining many lines of code once so that every time you need them, you don't have to define that code. Your mailer is defining many lines of code once so that when you ask for a mailer, you don't have to do it. Like you keep pointing out, even Laravel's components, all the illuminate components are effectively extra packages outside of Laravel Core that of course Laravel brings them in, and there's a service provider somewhere defining many lines of code once that then you don't have to run every time you need them. So I really appreciate you pointing that out.

Christoph Rumpel:
Thanks. Okay. Now, while you were talking, I also came up with two things that I had in my mind regarding the service container or where we make use of the service container. One thing I think we should talk about it also facades because they-

Matt Stauffer:
Oh, yeah. Of course.

Christoph Rumpel:
... make heavily use of the service container. Yeah. So just a basic explanation of what facades are. I think most people already know now. But I think it's good to give you a little reminders of facades are, give you a nice syntax in order to use a class that you can get through a static interface. So for example, when we use the route facade, it's route and colon-colon and then we have maybe a Git or post method and them we provide some arguments. When you take a look at this class, disrupt class, you will see that there is nothing in there. It's just to get facade accessor method, but not this get method.

Christoph Rumpel:
In the back, there are a lot of things that make this work, but what's interesting here is this get method or post method that we're using is actually part of a different class. The facade is just a link to a different class that we're actually using, which has maybe a longer name, or maybe it needs some things to set up, and it's not that simple to use the facade, and now, when we call the facade, we have a simple syntax. We don't need to spin up an instances. We call this static get method, and we get back what we want to achieve. But in the back, we are calling a different instance, and the container comes into play because it's gets facade accessor method of the facade itself, tells the container where to look for this instance that we actually want to use.

Christoph Rumpel:
So this means for the route or the request facade, there is a different request class that we're actually using, and the container now takes a look at maybe the request key or any different other key, and there now, it gets the instance back. So we can make use of a feature of Laravel with a much simpler or easy to read syntax, and yeah, people discuss facades a lot inside and outside of Laravel, and I don't want to go into that, but that's how facades actually make a lot of use of the service container and provides this functionality.

Matt Stauffer:
Yeah. I appreciate that the facades, despite how magical they feel are actually really, really simple. Each facade has a key map to it, and that key is one of those keys and values that you had described earlier being in the container. Right? Remember everything that we can instantiate out of the container is mapped to a key, and the first key it's mapped to is usually its class or its interface. But the second thing is often, especially with stuff that Laravel binds. They also give a shortcut key, which is usually just like a single all lowercase word, like mailer or logger or something like that.

Matt Stauffer:
So all the facades do is just say, "Hey, when somebody calls a method on this facade, go get me an instance of something on the container with a particular key," and the facade class only defines that key, nothing else and then instantiate something from that key. So give me an instance of it and then run that method on it. So if you were to run route::git, it says, "Okay. Well, I'm going to go to the route facade. I'm going to figure out what that key is. Oh, it's R-O-U T-E-R. Great. I'm going to go to the application. I'm going to ask for an instance of the thing, R-O-U-T-E-R. I'm going to then run whatever method was called on this facade on that instance."

Matt Stauffer:
So you do a route::git. It's equivalent to the global app helper, asking it to give you an instance of router and then arrow and then git. It's just a shortcut to make it more expressive and convenient. But in the end, you're still just asking for an instance out of the container and then doing stuff on it. So really, really, really glad that you brought that up, because it's so much simpler than it seems, and yet it provides so much for us in terms of expressive and clean and readable and simple code. So great note there.

Christoph Rumpel:
Yeah. Thanks for summing this up again. To give your thoughts on that, and I think when you think about facades in the end, it's pretty simple when you understood the concept and when you once go through how this is working. But before that, yeah, people are talking a lot about it in a lot of things why they are bad and why you shouldn't use them and what's good and bad about that. This makes it also a little bit of complex to understand, especially at the beginning. With Laravel, it's cool because you can use all the things without really understanding them. So route model binding, another topic maybe where we use the container or dependency injection for a constructor where we get an instance back.

Christoph Rumpel:
So all the things are very easy using a facade, and that's pretty cool because this makes it, as a beginner, very easy to start. But there comes a time when you need to understand, how are those working, and why do I get this arrow while I was working at this and to connect all the things. That is a good time to check it out a little bit more, and this is why I think it's, yeah, important to also check out the code, how this is implemented, and yeah, it takes a little bit of time, especially with some magic Laravel does. Yeah. It's not that easy to find this class that you're actually using, maybe. But once you have a checked that, it clears everything up, and it's like, "Oh, well. Okay. That's it." It's just a different class we're using, and that's okay.

Christoph Rumpel:
What we're talking about facade thing, it's always interesting how it was interesting to talk about testing facades because that's also something that the service container's pretty cool to use for. So the facades like notification facade, the male facade, we have also some testing features for those facades. What we can do in our tests at the top. You can run the fake method for example, on the notification facade, and now what we do is we're going to swap out the implementation of the notification instance that we're using. You know how facades work. It's pretty cool because we just have a key and reconnected to a class. But since this class in the container, it's not the class, not the facade that we're using. We can easily change what this is connected to.

Christoph Rumpel:
Now, with this fake method, in the back, Laravel is calling a different class, a dummy class, a fake class, which is not actually running this code. So when we used this notification fake method in our test, and we don't have a real implementation of the notification system anymore. So we can send out accidentally any messages to our users, and this is also pretty cool because, yeah, we can swap out implementations, and this makes testing pretty cool. This is also why I love to talk about this regarding facades, because a lot of people say that it's hard to test, which is normally the case with the static methods.

Christoph Rumpel:
But if you know this, and if you can swap out implementation, it's sometimes easier using facades, especially when facades like notification façade then provide some more methods like assert that a notification was sent a specific use or assert it was not sent, and this is a pretty nice syntax and gives you very good readability now in your test as well. So I think this is also what I love about the container. You can use it with facades and easily swap out what you want to give back for test.

Matt Stauffer:
Yeah. I think that's a great point for us to dig a little bit further into is the fact that the container makes testing and swapping and tests easier, even when you're not dealing with the facades. So let's say that I have that mailer as a dependency of my order, like you were saying. But I don't want to send mail every single time I do an order. Could you talk a little bit about what it looks like to... Now, I guess that's probably not a good example because we can just change the config. Let's say I made a custom Slack notifier of my own volition. I'm not using the notification class. I literally wrote the PHP code myself, and every single time an order is sent, I also send a thing over to my company's Slack, and I want to run some tests against fulfilling orders, but now I want to make it so that the class no longer sends the things.

Matt Stauffer:
Now obviously, one way would be to put a conditional in the code that says if testing, then don't send this. But how do we use the container instead to make it so that that notification thing does not actually send it anymore?

Christoph Rumpel:
Yeah. So the one way that I would think of is similar to facades, we can now insert our tasks, swap out what is binded to the class that we use in our code. So now a code call the container for this Slack messaging system or whatever it is, then we can, in our test, for example, bind something different lead to the same key, and now when we go to our test codes, to your code and tries to get this instance, now it gets a different one.

Matt Stauffer:
Yes. Which is wonderful, right.

Christoph Rumpel:
But it's pretty cool, because it's so easy. Yeah. Right.

Matt Stauffer:
Yeah. It's not only easy so that if you want to make a dumb Slack mailer that just doesn't do anything, but you can also instead, if you want to get a little more complicated, make a mockery and don't worry if you all are not familiar with mockery, but just, if you wanted to have a version of the Slack class that was recreated by a tool called mockery, that allows you to say, I want to assert that particular methods were called in the Slack class. You can make that instance using mockery, which we'll talk about in the testing. I don't know. Yeah. I don't know if we talked about mockery in the testing one, because I realized I had recorded it. So anyway, there's a thing called mockery that makes it really easy for you to make a mock, a duplicate of any of your classes and say, "But instead of doing what it should do, I want you to allow it to say, 'I should have this method called on me.'"

Matt Stauffer:
So for example, your Slack notifier might say, "I should, at some point during the span of this test, have the notify method called on me." Then just like Christoph was talking about, instead of the container resolving your Slack notifier, just in that test, you say, "Hey, whenever anything in the span of this test asks for an instance of Slack notifier, instead give them this mocked version." So not only are you not sending notifications, but now you also are allowing yourself to assert that as a part of this order publishing process, this Slack notifier's having a message sent to it, basically saying, send a notification.

Matt Stauffer:
So there's all these really cool things you can do, where using the controller or using the container really advances your ability to do rich and robust and simple testing. I love when, like you said, on day one, you don't even need to know how this thing works. But as you get more advanced, it turns out it's actually giving you the facility to do more advanced patterns and to do better programming practices that you didn't even know that you were building into your applications on day one. You just knew it was convenient to use facades or whatever. Turns out it's actually preparing you for your next steps.

Matt Stauffer:
I also really wanted to say I really love that idea that you said, which is that, on day one, you don't need to understand how the things work. But eventually, you do need to learn, which I think everyone would agree with. But there's a point you made that I love, which is that one of the main times you need to learn how the things work is when something breaks. If something breaks, having the knowledge of how the underlying systems work is going to just make a massive difference for you in the ability to understand what's broken and to debug it, and something that could just seem like this really overwhelming thing you say, "Well, class not available or key not available. I don't know what that means."

Matt Stauffer:
Well, if you understand how facades work, then you go, "Oh, I made a typo when the accessor method or whatever else it ends up being and then it's... So yeah. I love that. Thank you so much for that.

Christoph Rumpel:
Yeah. Welcome. Yeah. With a framework like Laravel, they have a lot of frameworks. They're very complex applications, and there are a lot of things happening in the back, and this is why the arrows that you see, I'm not immediately telling you, "Okay. It was this file, this line of code that you wrote." Yeah. That's something that we have to deal with because it's not so easy to understand for the framework why this error happened. It just tells you that it happened. The more you know about the framework, the better you are putting the pieces together and understanding, "Oh, okay."

Christoph Rumpel:
This is why mostly when we have an error we google it, and then, okay, try this, and that's totally fine. But if you encounter this problem, maybe the fourth or the fifth time, maybe at this point, it's a good idea.

Matt Stauffer:
This time.

Christoph Rumpel:
You don't google it now, now maybe you want to check out why this is happening.

Matt Stauffer:
I love that.

Christoph Rumpel:
I know this takes a lot of effort time, and sometimes we just want to, yeah, make our deadlines work, and we can do this all the time. But yeah. Every once, you should do this and give you some minutes to check this out, and it will help you a lot, and we'll give you a lot of bonus for the next time.

Matt Stauffer:
Yeah. I love that. So we've talked a lot about dependency injection, which I think is definitely the right place to talk about it. So I think if anybody ever sees the phrase dependency injection container, it's going to make sense, right? This is the main tool that we're using to do dependency injection. I also think that if we talk about a service container, it kind of makes sense because you can think of... I mean, service is one of those overused words in programming, right? But each of these packages or whatever we're bringing in is a service, right? So there's the mailer service, the logger service. Can we talk really briefly? I know this is maybe a little bit more advanced about inversion of control. Could you talk about what inversion of control means and why this container is a tool for inversion of control or IOC?

Christoph Rumpel:
Yeah. Good point. So IOC is also something that was like, "Oh my God, what's that. I have no idea." Then I read two articles and like, "Okay. I have no idea still." Yeah. It doesn't help. I like to put this very basic. I think that's fine to just know the basic of what it means. So when we talked before, when we had our order class and we created our tens lines of mailer instance inside our order class, then all this information about how to create the order, and then we also need to create the mailer is at the bottom of our code. So it's right at the end where we're going to use it.

Christoph Rumpel:
Yeah. As we mentioned, this is not that ideal because yeah, if we use it multiple times, and we need to change it at multiple places, and now our order has a lot of information about the mailer, which gives you a lot of overhead. The more code you have, the more complex, your architecture. You want to separate things and make it as easy as possible if you check out just a class or a method, and you want to keep everything clean. One way to do this would help you is inversion of control, which basically means we want to push up the knowledge to a layer at the top.

Christoph Rumpel:
So now at the top, we want to define, okay, if we want the mailer, give this back. Now, at the end of our code, at the bottom, when we use it, we can just call it, and we get the instance, and now our order class doesn't have control on how to create the mailer.

Matt Stauffer:
Love that.

Christoph Rumpel:
So that's basically how I like to think of it.

Matt Stauffer:
Yeah. So one example of that would be, let's say a couple of years back, one of the main transactional email providers went from being free to not being free. It was Mailchimp's... I can't remember what it was, but let's say that you had been using that transactional email provider, and every time you asked for a mailer, like Christoph was talking about, you would have the code to say, "Give me a new instance of that particular mailer, and here's the username, and here's the password pulled out of the config or whatever."

Matt Stauffer:
So 10 places around your application, you had that control of, which mailer are we using, and how do I instantiate it? 10 different places. Now, you want to switch over to a new mailer, let's say Mailgun or something like that, Mandrill, that's what it was. So you want to move from Mandrill to Mailgun, right? So now, you have to go 10 places in your application and switch out from Mandrill to Mailgun. So when he was talking about the bottom, I think what he means the most, I love that analogy of a top and a bottom. The top of your code is the abstraction, the configuration, the service providers and the things that are like run once and then pulled multiple.

Matt Stauffer:
The bottom is the actual consuming code, things like controllers and views and stuff like that. So when you have the control over which mailer you're using, for example, at the bottom, then changing it, it can be a big pain because you got to now do as this Global Find and Replace for all the places you were instantiating Mandrill and replace it with Mailgun, and what if you miss one, because it was typed a little bit differently than another one, and they were indented differently.

Matt Stauffer:
Whereas if at one point in your application you say, "Anytime, somebody asks for a mailer, give them an instance of Mandrill configured like this and a separate service provider." Then all your consuming code just says, "Hey, give me a mailer." You've inverted the control, and the control over how to do that thing is now up at the top. Therefore, switching from Mandril to Mailgun is in one service provider. One time you change that code, and then it's done forever. So Christoph, you explained it perfectly. I really, really appreciate that. So now we know why it's an IOC container, right? It facilitates that inversion of control because we're binding at once with whatever the definition is and then never thinking about it ever again.

Christoph Rumpel:
Yeah. Right. It's an IOC container because it helps you to think or make use of the IOC content, and it's a dependency injection container because it helps you with dependency injection.

Matt Stauffer:
Love it.

Christoph Rumpel:
So I think that's good to know. One more thing I want to add here, which we haven't talked about is interfaces. Yeah. So that's also interesting, and I think we should talk just briefly about it. So instead of binding to a specific key or classmen, we can buy something to an interface. So let's say for this example, we have a mail service interface, and here we define, yeah, the main methods that we need for our mail servers like to have and to send something to, yeah, I don't know, whatever.

Christoph Rumpel:
Now that we combine to an interface, we can tell Laravel, okay, what a service container, when someone asks for its interface. So for example, inside our controller, inside the constructor, we're making use of type hinting, and with type hinting is interface. Now, inside our container, we can define that someone asks for this interface, we want to give back a specific instance. This is also what we can define, and this gets pretty powerful because now everywhere in our code, we don't have to type hint the Mailchimp service, for example.

Christoph Rumpel:
So we're just type hinting an interface, the mail service, and now, like you said, if we now need to change our middle service, we only need to go to this one service provider and change. When a user asks for the mail service interface, we don't want to give back the Mailchimp implementation. We want to give back whatever different service implementation. This gets really interesting because we then also have something with contextual binding, where we say, if this class asks for this, we give back this. If another class asks for the same thing, we want to give back something differently.

Matt Stauffer:
Yeah. I love that. If anybody's not familiar with interfaces and PHP, they're basically the ability to say here's a contract between the people who are authoring these very similar PHP classes and the consumers that anything that claims that it's implementing this contract will provide at least these methods basically shaped this way. So an interface allows you to say, maybe we have 10 mailers, Mailgun, Mandrill, and all the other ones. But all of them implement the illuminate mailer contract, which says they've a send method or whatever else method. Right?

Matt Stauffer:
So like Christoph was saying, you can type hint that interface instead of the specific mailer. So that's one where by default, the container doesn't know what to do, right? If you just type in an interface, the container says, I don't know which instance of it you want or which implementation of it you want. So that's where in a service provider somewhere you say, "Well, every time somebody asks for this particular interface, give me Mailchimp." So it's very similar to the example we gave before, where if that's how you're working on it, then you just say, "Okay. Well, next time, instead of Mailchimp, give me... Or instead of Mandrill, give me whatever the other one was, Mailgun." They'll will start with. Yeah. Great, great, great point on that.

Christoph Rumpel:
Yeah. As you said, normally, we can't type in that interface because we can't provide an instance of interface because you can't create an instance of an interface. It's just like you say, the contract where you say, "Okay. We have similar classes, and they all should have the same methods so that they are easy to use and easy to swap out, and that's why it's so cool to type in that interface.

Matt Stauffer:
All right. So one of the sections I always try to cover on the podcast for these things is what are ways where you commonly see people getting tripped up or confused or common challenges that you see people running into when it comes to the container?

Christoph Rumpel:
Good point. So as I mentioned before, I think the whole topic is quite complex. We have the terminology, which can be difficult. So I think it's in general, difficult to, yeah, understand what the container does and how to use it. So this is when I say it's really important to read a lot of different articles or videos about it because everybody teaches it a little bit different, and it's personal to you what other things that clicks for you. This is also why I want to provide it with my video and articulate about it a different few to the ones that I watched before, which didn't help me.

Christoph Rumpel:
So yeah, now that I think about, I think it was the first Laracon EU that I went, I think you were speaking there in Amsterdam about empathy, so the first Laracon EU. It was, yeah, one of my favorite talks. A lot of people say there was really cool, and I think it was the same conference where Hannes Van De Vreken were talking about a service container. It was like, "Yeah, super cool. Because I don't understand that, and I'm glad that there is a talk."

Christoph Rumpel:
Yeah. 10 minutes into the talk, I was like, "Okay. I have no idea what he's talking about, and it didn't help me ahead. Oh, yeah." Yeah. The talk wasn't bad. So it was really good, but I wasn't the right situation for how he presented it, and I needed some different experimentation. This is why I think it's interesting and important to check out different resources, especially regarding the service container, because there are many ways and how to think of it, and some clicks more to you than the other. So that's in general speaking about, what are some common gotchas. Then as I said, terminology makes it a little bit easier, a little bit difficult, and also, there are a lot of things hidden.

Christoph Rumpel:
You don't see the things that you use sometimes, and yeah, especially when you're typing something, and you don't see how this is working. This is a perfect example because a lot of people type hint somewhere else in your classes, something, and now they wonder, "Okay. Why don't I get an instance bag like it works in a controller?" I'm sure this happened to me as well, but I tried it in a different class. I was like, "Okay. Why doesn't this work I think in models that don't work?" It was like, "Okay. Well, this is not working." I thought if I type hint something, then I get back an instance back. But that's not how PHP works. It's just a feature that Laravel provides.

Christoph Rumpel:
So I think this is also when it's interesting to know why this is working and when this is working. So that's a common gotcha that I run into and-

Matt Stauffer:
Very important.

Christoph Rumpel:
... I'm sure a lot of people as well. I think that's the common gotchas that I have. It's difficult in general, and you need to check out different resources and give yourself time to understand it because it's not that easy. It's not the first time when you read something about it that it will click, but there will come a time when it will be like, "Oh, okay. I see. That's cool." It was a little bit for me also with your talk about service container, because the thing with the boxes is also something that helped me a lot. Keep it simple. There are boxes you can put things in, and then you get it back out, and that's something that I can work with them. Every brain works differently. So that's why you have different resources are very cool here for this project.

Matt Stauffer:
Yeah. I'm definitely going to keep thinking around this analogy that you came up with, where you have the two parents and one parent knows what the kid wants, and the other parent was the one implementing. So because one of the downsides of the boxes idea that I came up with is that you're putting something in and taking something out. But in reality, it's more like you're teaching a relatively... You know what, I think what I'm going to start thinking of is there's like a robot, and the robot is running the birthday party, and each of the parents have taught the robot a little bit about what this kid likes, and the robot has no ability to empathize with the kid or anything like that. The robot can only, when asked for something, reach into its memory banks.

Matt Stauffer:
So the kid asks for a cake, and it says, "Go into the memory banks for a cake or whatever." It says, "Oh, I remember. The dad's the Baker. The dad told me about how to make the chocolate cake exactly the right way." Right? Then it reaches to its memory banks for toys, and it's like, "Oh, the mom said that he was playing with Bakugan, and so I'm going to go whatever." I love this because it involves the fact that it's not just a box that you put putting things in and taking out of. It's a system that you're teaching how to generate the thing that you need. So this is one of my favorites that I've heard. So really, really good work on that.

Christoph Rumpel:
I love that. Yeah. That's even better with the robot, and this way, we also don't need the father who doesn't know too much about his kids.

Matt Stauffer:
I mean, I want good. We're just always working on the narratives.

Christoph Rumpel:
Yeah. Okay. Lucky now we have the birthday party with the robot. Yeah. It's cool.

Matt Stauffer:
I love it. I really loved that. I think it's probably the most robust analogy I've heard yet. So really fantastic work on creating that.

Christoph Rumpel:
Nice.

Matt Stauffer:
But your point is very good, which is that everybody learns a little bit different, and each of us is going to find something that clicks a little bit different with us. There's also something you brought up, which is just that sometimes we get surprised when we try to use dependency injection, and it doesn't work. One of the things you'll notice is that as you start getting used to dependency injection, you're more and more are going to start using constructor dependency injection in your custom classes.

Matt Stauffer:
When you write a PHP class, you're going to get more and more used to just when you want something, you put it in the constructor, and then later you might new it up, literally just say, blah, blah, blah equals new and then your new class and go, "Wait a minute. I have to build all these dependencies. I wasn't expecting that." So the simplest answer in that circumstance is to just, instead of doing new, whatever, you wrap it in the app, global helper. If you pass a class name to the app, global helper, it's exactly the same as newing it up, except the container will take the responsibility for generating, resolving, and then injecting those dependencies for you.

Matt Stauffer:
So granted you want to be a little careful of using the app helper too often only because sometimes the app helper introduces some of the same problems that we get by newing up our classes in line are also introduced by using the app helper in line, so anytime you find yourself using the app helper, the next question to ask is, could I dependency inject this into the thing I'm working in now? Right? So there's steps. But the basic idea of use more dependency injection and know why it's not working sometimes, and then learn that even when it's not working, there's still always tools for you to get that same benefit of the automatic dependency injection to the container provides. You might just have to do an extra step if you're not in a controller or whatever else. So really, really, really good points there.

Matt Stauffer:
You already mentioned a few. But are there any other articles or tutorials or anything like that on this topic? So you mentioned, and we'll link all these in the show notes. We'll harnesses this talk. We'll put up my talk. We'll put up core ventures. Is there anything else that you think people should take a look at as a resource for learning about the container?

Christoph Rumpel:
Yeah, I'm definitely a fan of my video I did about it because it clicked for me, and I also I heard a lot of good feedback for people who were the common, or they're given resources didn't help. So I'm really glad that I could provide this for others. So that's a blog article I wrote about it, the thing it's called the best way to explain a service container, and there's also a video that I have in my course, which is for free. So these are two things, then there's also your talk, which I think is pretty good, which we should mention. Then there's also some videos on Laracasts. I'm not sure if they're free will, but I think they are. I think they were in Laravel from Crash, and I think that's for free, right?

Matt Stauffer:
I think so. Yeah. There usually is.

Christoph Rumpel:
Yeah. So they have a few videos about service container and service providers. The cool thing about which I feel, it creates a service container from scratch rather easily, and I think this also helps to see, "Oh, okay. That's a basic implementation of a service container." So this is also cool to check out, and I think there's another talk, yeah, also, at Laracon EU, I think it was last year by K, and it's also about the service container.

Matt Stauffer:
Oh, cool.

Christoph Rumpel:
So we have a lot of good resources out there. So yeah. Check them all out there. There's one resource for everybody, and it's cool that a lot of people share their opinions and their thoughts about this topic.

Matt Stauffer:
Yeah. We'll link all that in the show notes, for sure. But before we go, there's a fun topic I have to ask everybody. For you, I'm super curious, there's a guitar hanging in the back. Can you tell me a little bit about your musicality? Yes, exactly. There's a guitar hanging behind you. They can't see it, but I can see it. Tell me about your relationship with music.

Christoph Rumpel:
Yeah. That's funny. So when I was in school, I think it was 14 years old, I was totally into punk rock, and I had a few friends. There were two. Yeah, we just started the punk rock band-

Matt Stauffer:
Nice.

Christoph Rumpel:
... back then. Yeah. I had no idea of how to play a guitar. We just liked it-

Matt Stauffer:
Let's just start a band now.

Christoph Rumpel:
...It was like, "Okay. There's one guy. I think he can sing a little bit. So what are you going to do?" I was like, "I have no idea." "Then okay. Maybe you can try guitar as well." "Okay." Then I took some lessons, and now I was a guitar player.

Matt Stauffer:
I love that.

Christoph Rumpel:
Yeah. It was really cool.

Matt Stauffer:
Do you still play at all.

Christoph Rumpel:
But just a little bit. But the band, we had over 10 years and-

Matt Stauffer:
Is there other recordings online?

Christoph Rumpel:
Yeah. We have three albums out there, and yeah, we played about 150 shows.

Matt Stauffer:
Wow.

Christoph Rumpel:
It was a random little tours in Europe. So we tried to make it professional. But yeah, it was really hard.

Matt Stauffer:
It's hard.

Christoph Rumpel:
At some point, yeah, we saw it didn't work out. Then you have to put so much time in and so difficult to make money from it as well, especially coming from a small country like Australia. Yeah. At some point I think after the third album, we said, "Okay. It seems like this was our last tribe. It was good. We had our achievements." But it wasn't like, "Okay, we can lift on that." That was when I started looking more into programming and coding, and I started-

Matt Stauffer:
Oh, cool.

Christoph Rumpel:
... studying at university, and yeah, this is how I came to program.

Matt Stauffer:
That's a really cool... I mean, it's not cool that it didn't work out, but I had always assumed, because I knew you're a musician, but sometimes I ask this questions just so everyone else gets to get the benefit of the answer. But I didn't know that, because I had assumed that you were doing both. So that's really interesting to hear. Well, I'll ask you to DME the links later, and we can put them on the show notes, if you don't mind.

Christoph Rumpel:
Yeah. I can do that. We also have some very old, funny videos.

Matt Stauffer:
Yes. Yeah. We'll link it all up. I love that.

Christoph Rumpel:
Yeah. It was a different time back then creating music, but yeah.

Matt Stauffer:
Yeah. It's fun kind of just reflecting on how much creativity there is among programmers, and you just got a lot of musicians, a lot of artists, because what we're doing is inherently creative in a lot of ways. So-

Christoph Rumpel:
Yeah. I also want to mention here it was cool because of music, always how to deal with designing events shirts, designing the band website, and stuff like this. We made some videos ourselves. So as a band, you do everything yourself at the beginning, and this is how I came into all those topics, designing and little bit of programming, and I still remember our Myspace side. Sort of people still know Myspace, but basically back then, you had a MySpace page, and there was all the information about the band. So everybody would go to Myspace to hear songs, to see your photos, to know about your next concerts. There was this little input for how you create your styles for Myspace page.

Christoph Rumpel:
Yep. Back then it was like hacking because we wrote a bunch of HTML and CSS, and we put it into this one input and this way, we could change the whole look of the page, yep, and it was like we're putting this code, and we had no idea what we were doing with just copying stuff and changing some numbers, and then we hope that we get this pretty cool sites. So this was really interesting. Yeah. It's funny because this is how I came into the things that I do now.

Matt Stauffer:
Yeah. I love that. I actually think that I've had a couple other guests mention that Myspace was one of their first introductions to coding as well, because you knew what you wanted it to look like, and you know you wanted to look cooler and more customized in everybody else's, so everyone's trading little snippets and trying to tweak them and see if they can not break the whole thing. So that's awesome.

Christoph Rumpel:
Yeah. You have this one big background image, and then you had the video player, and then you try to provide a space inside this background image, and you try to position it right-

Matt Stauffer:
Yeah.

Christoph Rumpel:
... on this space so that it looks cool with a little frame or something like this. Back then we didn't have responsive sites or something like that. So it was just a big background image with putting some stuff on it. Yeah. We went crazy.

Matt Stauffer:
Oh, man. You just gave me flashbacks of like, how big does your background image need to be? Oh well, it only needs to be like a thousand pixels wide, and then people would get bigger screens, and everyone was, "Oh no, we need to make our things bigger now."

Christoph Rumpel:
Oh, no.

Matt Stauffer:
Gosh. I had not remembered that particular aspect of it for a long time. All right. So because we are a little bit past time, as always, I could talk to you forever. I didn't even need to say that anymore. How do people follow you? We've talked about Laravel Core Adventures, but what's your Twitter, and are there any other places you want people to be interacting with you?

Christoph Rumpel:
Yeah. So I'm mainly on Twitter. My Twitter handle is just my name, christophrumpel, and one word together. I tweet about what I do about, my blog posts, giving talks about consulting, freelancing, everything related PHP, Laravel, and my one-man business. So if you're interested in that, check out my Twitter handle. Then I have, of course my blog, which is christoph-rumpel.com, where I have my blog posts. As you mentioned, the video course laravelcoreadventures.com, where, yeah, I teach those concepts that I wanted to understand myself, and in order to do this, I created those videos, and now I know more about it, and I can also share what I learned with this course. So I think that those are pretty cool and a win-win for me.

Matt Stauffer:
I love it. Yes. It's amazing how much we can learn when we decide to teach. Right?

Christoph Rumpel:
Yeah. Right. Yeah.

Matt Stauffer:
Well, Christoph, this was an incredible amount of fun, especially with such a complicated topic to try and delve into each of them, and I loved being in a space where I think, like you mentioned, I think this is one where it is a little more difficult to learn and each person has a different perspective. So it was fun being able to bounce back and forth with you where each of us, even now, having learned it and taught it before, both of us has a little bit different angle. So hopefully between the two of us, we gave y'all a little bit of a broader opportunity to sometimes like Christoph's answers better, or sometimes like my answer better, sometimes what you get from both of them. But know that this is not the end, right?

Matt Stauffer:
We are only two perspectives, and we only got as far as we could in 50 minutes. So go take a look at those other resources everybody. It's really good stuff. Definitely check out Laravel Core Adventures. Christoph, thank you so much. It was a ton of fun hanging out with you today. I really appreciate you joining.

Christoph Rumpel:
Yeah. Thank you so much too for having me, and like you said, bouncing this topic back and forth between other things was really helpful for me as well. So yeah. Thank you and also thank you for having this serious with this podcast because, yeah, I enjoy every episode, and yeah, as mentioned, I'm doing Laravel now for a long time, but still every episode, there are some new aspects that I learn, and I like that. I also like that you're doing, or that your intention of doing this is also for beginners to, yeah, get some resources, hear people talking about this because, yeah, it's important to, yeah, teach to people who doesn't know too much about them and give them more resources to learn. So thank you too.

Matt Stauffer:
Thank you. I really appreciate that. Well, we'll see all next time. I don't even remember what the top is going to be, but it's going to be a lot of fun, and Christoph, I'll see you later.

Christoph Rumpel:
Yeah. See you. Thank you.

Matt Stauffer:
Thank you.