 So the room is full. I think we should proceed. Doors are closing. Thank you for coming. So I have two minutes to do some advertising. No, that won't last two minutes. I'm the CTO of Blackfire, which is a PHP profiler. It is able to display and to show you what happens in your application, in your scripts, in terms of call graphs. So this is a short excerpt from a call graph. And I'm very happy today to announce the profiler edition, which is a new way to add more features to Blackfire. So if you want to try it, it's free. And if you want to use it daily, it's also free. But if you want more features, you can use this coupon, a profiler launch, to get discounts on the profiler edition. OK, let's go. So the topic of today is mastering dependency injection in Drupal 8. I'm Nicolas Grecaz. I'm French. I work at Sensualabs in Paris. So I work for Blackfire also, which is a business unit of Sensualabs. Sensualabs is the company that is behind the symphony framework, so symphony components also. It has been funded by Fabien Potentier, which you may have heard of because he leads the symphony in the open source community there. I have quite some time. Fabien allows me to work on symphony and to hack on symphony. So I'm quite active contributor now. And that's it for the presentation. Don't hesitate to tweet and give feedback at the end of the conference, during the conference. It's very important for all speakers here and for the Drupal Association to keep the good speakers right there. So I have a lot of code in my slides, so I hope you won't be too scared of them. Let's talk about design pattern, yes. So the dependency injection design pattern that forwards maybe overloaded them too complex for what they are really. So let's say we have a user. This is a really simple user class, and our user has a language property, so we are able to store in which language this user wants to see the pages. So we have a method set language, and, of course, it's just a setter, very basic one. So to use that user class, we instantiate it with user again new user, then set language, and then we have an English-speaking user, or at least reading. Now let's say we'd like to store the language of this user in the session. So let's create a session storage, which is just a wrapper around PHP sessions. So we have a constructor with a cookie name. The cookie name, this is the default of PHP also. So PHP says ID. We use session name, which is the PHP function to set the name of the cookie for storing session, and we start the session. Our cookie storage has a setter, which is, okay, set this key with this value for this key for the session, and that's it. Okay, so that's just a plain wrapper. Let's use it in our user class to store across pages the preferred language of our user. So this is a way to do it. Let's say our user needs the storage, of course, so let's have it as a property built in the constructor of our object. So now we have a storage as a private property, and when we set the language, in fact, we store the language value in the session, in the language property. Right, straight forward, I guess. And to use it, exactly the same code here. We say new user set language, English, and now this will persist across pages. Okay, now we have some issues with this code. In terms of decoupling reusability, how do I create a user that uses a different cookie name? So as you remember, the session storage has a parameter, cookie name, and the default value is php.sid. And now this is hardcoded into the user class. A user must have, with this code, a cookie name, which is called php.sid, which might be bad. We don't want that kind of hardcoding into classes. Another issue there is the session storage itself, because this is a session, and this is the actual PHP session, but maybe in your unit test suite, you'd like to not have the real session storage engine, but you may like to have another storage, some array storage, local storage, or maybe you'd like to have some memcached storage, ready storage to store the session and not use PHP native system. So now that's another issue we have here. So how do we configure the storage when it's hardcoded there? We can't, okay? So for that, there is a way to do that. It's just to inject the storage as a constructor argument. Now, I just have to configure the storage from the outside of the user class, and I give it ready bootstrapped to the user class when instantiated it. And that's the code that does exactly this, okay? So we create the storage, but we could create ready storage and array storage. We could pass the cookie name there and give it ready to the user class, and then it's ready. We have decoupled things, and we're ready to handle many storage engines. Really, that's the design pattern. That's dependency injection. Dependency injection just means not instantiating hard coding things into classes, but really giving them ready to your classes, to your own classes. And that's it. Now, so we have the concept. Let's get deeper into that. So back to our user class. We have the storage here. As you can see, there is a type issue there. There is nothing that guarantees you that storage is actually a session storage, which means it could be an array, it could be a string, it could be anything. So there's a way to enforce that, which is just to type hints using PHP type hints. So let's say we created some session storage interface. This could just define our set method. And then in this case, we are sure now that the storage will be and must be something that we can deal from the user class point of view. Deal with it, okay? Now we have other way to do dependency injection. So I showed you constructor injection because we just injected the storage into the constructor, but we can of course use setter injection. So in this case, we added some set storage method on the class. And now we just have to call the set storage method to configure the session storage for this user class. The third and only last way to inject a dependency into some class is to use public property. So no method, just a public property. I just wanted to show you that, but you shouldn't do it because you don't have any type hints there. You don't know, there's no extension point, so there is nothing you can hook and it's not extendable and reusable. So constructor injection is better than setter injection, which is itself far better than property injection. Setter injection has an issue, which is that it makes the object, the user class mutable, which means you can call set storage several times and you just change the storage, which can be an issue. With constructor injection, you are sure, if you didn't do some crazy hacks, you are sure that the storage will remain the same from the beginning to the end of the request cycle. Okay, so it's rule of thumb, dependency injection as a design pattern is like never writing new in your code. If you see new something, then it means there is a possibility for maybe using dependency injection instead of hard coding this very class that you instantiated like our new station storage at the beginning. And dependency injection is for adding behavior and features to your objects. So that's the asterisks at the bottom. You also will deal with data objects. So for example, a date time, PHP plane, date time object, this is fine to do into your class date or now equals new date time because date time is really a data object. It's just proper for state and for date and you don't want to inject the date as a dependency because you don't care about that. You just want to have some value holder object. So it's fine for data object to have new in your code but really for anything else, you should think twice and say, okay, this is a new. I'm just reading a new in my code. Maybe there's something wrong. Maybe I can decouple it and make it more testable, more reusable, easier to review, more focused also on its own and very responsibility, things like that. That's it. So dependency injection allows you to make code reusable, testable, pluggable, loosely decoupled, many words we like. Let's construct on the concept. So this could be a dependency graph or this shows some alternatives that we can have when dealing with our user class. So at the top we have the user class and the user class needs a session storage interface of any kind. So that's the name of the interface in green and then let's say we could have a session storage. So the first or the second class in the slides. This session storage itself has a dependency which is not an object, it's a string, it's the name of the cookie. We could have the array storage, of course, which is perfectly valid from the user point of view. The user point of view really doesn't care about whether it's a session storage and array storage or maybe in this example, a ready storage. So ready is a database in memory database that is really fast and really, you know, suited for storing session and other things but for session in this case. So let's say we have some ready storage that implements the session storage interface and let's say maybe that this ready storage needs itself a ready disconnection which is something that PHP or some PHP extension can provide. So that's another object and I'm sure the ready disconnection object itself needs to be, you know, to get some ready host which is the server where ready is listening. So local host or something else. So as you can see with dependency injection, we start to have dependency trees, reverse dependency trees. So I need a user, okay, to get a user who you first need to get a storage. Oh, it's a ready storage. Then you need to build a ready disconnection and then, okay, first you just give me the ready host and this is a chain and if you think and if you build your framework and your application on this concept, you will get a big tree of dependencies. And if you need, for example, a logger, let's say the logger service is an object that implement something but maybe the logger needs database if you'd like to log in the database and so on. So all services have dependencies. And to deal with that, we need something, some code that knows how to create a ready disconnection, a ready storage, a session storage, maybe a user. So we need recipes for, you know, new session storage. This is needed as first argument of the user class and so on. So we need these recipes and we also need some, you know, registry of services because in some page, in some application, you want to have only one session. This is the user session of the current request. You need to have one logger so that all the feature, all the code that need to log get this very same instance of the logger you're going to use everywhere in your application. So where should we, you know, index, register this list of objects that are useful and provide features to your applications? That's where we need the dependency injection container. So now we are talking about an actual object. Until now, I was speaking about, you know, dependency injection as a design pattern. So it's a concept and it's a really simple one, just injecting things instead of creating them inside the classes. Now I'm talking about an actual object, something we can read as code and create with a new keyword. So the dependency injection is an object that has all the recipes to create the actual object. So, and in fact, that has all the object of your application recursively because you know, we have this train in mind so that I need a session. Okay, you need a connection. Okay, you need a ready storage. Okay, I don't know how to do them and I know how to wire them so that the logger is injecting into the ready storage if we'd like to do that. The container knows everything about that and you're going to tell and to teach it how to do that. We call that, I already used that word, the services. So the services are really the useful object that the containers, the container knows about. Only that, actual objects. Okay, okay, let's start. This is a container. The container has a get method and it takes a string as an argument which is the nickname of the object you'd like to get. So let's say container give me the database and the container knows how to build this object because it has a recipe for this database string in its configuration. Drupal ships with a few hundred services so a few hundred recipes and nicknames for features that are ready for you to be used into the container. So this is a short excerpt and in the next slides I'm going to take them not one by one but the general ideas, focus on one type of definition and all the kind of definition you can use to create recipes and to give them a name. Okay, so the simplest recipe is this one. So this recipe says let's create a service which we call serialization.json, so it's just a string. And this service is just an instance of the Drupal component serialization json class. And that's it, if I give you this recipe you can say, you know, and because you also, you know that to create this service, so serialization.json, you just have to create an object with new Drupal component serialization json. So this is the kind of code that could be generated for the container to just return the serialization.json object. So let's say we wrap it into some, you know, getter and the code for creating this object is the last line new Drupal component serialization json which is exactly the same string as in the definition. And we put that into this services array. So this is the container and the container stores this new object into the internal array. So that whenever you call get on the public surface, the container can just call this method when the service is not ready, get the object and reuse it the next time for you, okay? So let's make it a bit more complex slides after slides. Let's say we need now a service which we call state. It's missing indentation. There's missing indentation in the class and arguments parameters. So class, same thing. That's the class of the state object, state service in fact. And in this case, the constructor needs one argument and this argument, so if we were to need several, you know there are the brackets, so comma, second argument, comma, third argument and then the first argument is a service, is another service. And this is the add symbol that say that. So this is saying to the container to build the state service, just create a new Drupal core state object with the key value service injected as first argument. And of course, it has to know how to build the key value service in another line of the same file. So this is the kind of code that the container could generate. So in this case, we say new Drupal core state state argument this container get key value. Okay, and this is where things can be recursive and you can trigger several get when you need the state service in this case. Continue. Okay, so we talked about setter injection on our user class. So this is another example of setter injection. So that's the definition for it. Let's say we have a service which is called urlgenerator.nonbubbling. I took example from the actual core.service.yaml file which exists in Drupal. They're not the latest version, so yeah, they look almost the same. So our service is an instance of, should be an instance of the Drupal core routing urlgenerator. It takes some arguments. Public, let's give me a minute to talk about that. Calls, calls is the list of method that should be called for building this object. So this tells new, the code generated should be new Drupal core. Then on the resulting instance, set context with the first argument which is router.requestContextService. A few comments there. As you can see, there is an interrogation mark after the add. This tells the container that whenever the service router.requestContextService doesn't exist, then it should inject the null value because it's possible that in some definition you use consume some service but this service is not defined because configuration has disabled some part, some features of the application and disabling them means the service this feature might define are not there. So this class should be able to deal with both a router.requestContextInstance and the null value. So about public now. So public false by default in Drupal 8 and in Symphony, all services are public. Public means you can get them from the container. So it's our container get database from the beginning. Database is there because it's a public service. If we set a service as private it means that you can't fetch it from the outside of the container. You can container get URL generator.nonbubbling. You will get some error because it's internal thing. How is it useful? Because you can use this string to inject to use it as a dependency to other services. So when doing the definition you can create services that don't exist from the outside but are still injected into some other dependency for building them. Okay, that's the kind of code. And as you can see, I didn't lie. So the first thing is creates our new Drupal URL generator with the arguments. Then if there is a router.requestContextService so it's a new method on the container, then we call the setContextMethod and we inject it the router.requestContextService and there's a second argument on get which is container interface, null on invalid reference which is readable enough to you know what it does. And that's it for that. That's one thing, next slide. Another way, so this is using the factory design pattern. Who knows about the factory design pattern? Okay, great, so the factory design pattern is the pattern where instantiating the object or some object is done by another function. So another function, another method. So let's say you have a function which is called factory. Then the job of this function is just to return an object. It created any kind you need and each factory returns its own kind of object. So if we have a database factory, in this case yes, we have a database factory, which is written in the database class so that the second line, you have factory, the first argument, the first value in the array is the name of the class of the factory and getConnection is the name of the method we need to call to get, in fact, the database. So the database should be a Drupal core database connection. It takes one argument, so default, which is required by getConnection. So this is Drupal configuration. I don't know exactly why this argument is required, but I'm sure it's because, okay, I can't tell you. It's because you have the default connection, but you also have the slave connection so you can do several connections, one for writing, the other one for reading from the database, things like that. So this is the generating code. A generated code is like this one. I removed, you know, the boilerplate. So to get the database, PHP will call the getConnection method on the database class with the default argument. That's it, that's the database design pattern. And the return value of this function call should be a database connection and we will register the container, we keep it in its registry of services. Another example with factories. So in this case we have the cache.cache.default, which is a class and the class is Drupal core cache, cache, cachepack and interface. So this is a more advanced definition for a factory because in fact, a factory doesn't have to return exactly that kind of object. I mean, by that kind, the name of a class. So a ready storage or a session storage or an early storage to map with the previous slides. It could just return any kind of instance of cache backend interface, so any kind of class that implements this interface. And that would be fine, you have enough, we have enough information to know what kind of object this returns. So our factory is now a service. So to create the cache, the default cache in fact, we use another service which is called cacheFactory and we call it's getMethod and the argument of the getMethod should be just default, okay? So that's the kind of call this will generate. So this getCacheFactory getDefault and this should return a cache backend interface object which we store into the cache.default service registry. Yeah? Now, using a configurator. So that's another way to configure objects. It's quite rare in practice. So I just added this slide for completeness. A configurator is a design pattern where you give some method an instance of some object. So the object is already there. You already have it at hand on the contrary from factories, in factories it returns the object. But for configurators, you already have the object and you tell some method, okay, now let's please configure this object for me. So we have the Gizel-Guzzle HTTP handler style. So HTTP handler stack as a service name. So this uses a factory. So Guzzle HTTP handler stack create method and this will return our object, our Guzzle handler stack. And on the return instance, we should call configure from the HTTP handler stack configurator service. And the generated code should look like this one. So we create our instance using call user fern. So calling the create method on the handler stack. This returns the handler stack object. And then we fetch the service HTTP handler stack configurator from the container and we configure it just by calling configure. So this is using the mutability of the instance object. So that's why also it's not recommended. It's not the best practice because this design pattern implies that instance is mutable, which means has setters, which means can be altered at runtime, which is something that shouldn't happen for services. Let's talk about that in a few slides. I told you that the container returns always the same instance of the logger of the database object that it's created. And in fact, that not mandatory. And the container is also able to return you a different instance each time you call it. So if you were to set shared false on the database object definition, service definition, then it would mean that calling container get database opens a new database connection every time, which is not what you'd like for database, but which is what you need for this feed reader Dublin core entry, which is a service provided by Drupal. So whenever you call container get feed reader Dublin core entry, you get one object. And if you call it a second time, you will get another object of the same built the same way, but still a new instance of this object. So we call this kind of services synthetic services. So this is a synthetic service because it's not shared and shared services are not synthetic. So shared and synthetic are the opposite words in the container vocabulary. There are several feed reader and feed writer object and services defined into Drupal. And they all are not shared because I guess they are just data objects. And this is using the container as a factory for feed reader and writer entries. Okay, let's continue. So I'd show you how you can write PHP code in YAML. Basically, that's it. By using the definition, it's just a new syntax, another syntax declarative one to create PHP code. And you have the YAML on top and PHP at the bottom. Now it's possible to go one step further and play with the definitions themselves. Saying, okay, now I deal with definition and I change them in some way. So the first and easiest way to play with definitions. So a definition is, we saw only definition in YAML right now. So this is another definition for the config.storage service. And the definition and the configuration for this service is very easy. It says, I'm just an alias for the config.storage.active service. Which means just copy past the definition that exists there and I'm using exactly the same definition. So, and in fact, not only the same definition, but also the same object. So I'm the same, I'm a new name for this name. Which means that the generated code is just this one. So if you ask for the config.storage service, this code will be called. Okay, that's an alias. It's very useful because you can define several, in this case, several config.storage. So you say, this is config.storage.active. This is config.storage.whatever1234. And in your code, you can say, okay, I have several config.storage ready for me. But the one I want to use is this config.storage. So at the beginning, in your service configuration, you say config.storage, my config.storage as alias. And this is just a matter of selecting quickly which of the existing definitions you are really using for this service. So, I didn't talk about parameters. Yet they're very useful and there are several of them. Parameters are plain data, PHP data. So usually a string, a parameter can be a string. Can be an array. Can be any static value, number, scalar, array of numbers, of scalar, string, and recursively, this kind of thing. So you have another section in these service files which is parameters and then just a key value store. So you store config.storage and the value of this one is in this case, foobar. And then you can use parameters in string. So the interpolation is using the person's symbol. So as you can see, we have person config.storage.person. And this is just the placeholder for the value that is actually set for the config.storage parameter. That's a really useful way to configure differently your production version and your development application. Let's say you have a parameter yamlify somewhere. In your dev, you might load some foobar config.storage and in your production, you might define the parameter to something else which is your more heavy ready storage or something real for production use and not only some development environment thing. And this should be resolved to, in this case, foobar. Very easy, straightforward. Okay, abstract services. So an abstract service is a service definition that you can't instantiate like an abstract class, which you can't new abstract class. This is not possible. For service, it's the same. So in this case, we have container.tray which is also a Drupal service. This one is abstract. You can't use it. It won't work. And what it defines is that the container.tray service is should call set container with the service container as first parameter of set container. And that's the short excerpt of the full definition that the actual service will need. Let me show you. This is not PHP code. This is YAML again. So this is to show you how this is used and this is also Drupal configuration. So in Drupal, there is a logger.factory service and this is what you're gonna use to log things. And this is an instance of the logger channel factory and there is a setter to be called on this one and it's the setter defined in the parent definition. So parent is the keyword that say, okay, copy past what's in the parent into my own definition and that's it. So it's exactly the same as doing, removing the parent line and copy-pasting the call line and putting it in the logger.factory service. So it's an easy way to share configuration in the abstract level and to define several services that need, that have a set container method and having this method take the service container a service as first argument. So also the service container is the name of the service container itself. I have a question there. I see here both trade and parent but could you use this as actual trade? So could you in the logger factory use multiple trades like you would in object oriented code? Okay, the answer is no. And that's very unfortunate and I think that's some idea. It's an unusual way to use parent in service definition inheritance. That's what I found in the definition and that might end up as something like you say, you know, having the way to have trade definition that doesn't exist yet. Okay, so you actually defined it as a trade but you can only inherit. Exactly, yeah. Yeah, but there's no type inheritance. So this is really a trade but a single trade. Okay, that's maybe the last example. Yet maybe also the more complex to understand. Let's say we have an app.mailer service. This one is virtual just for the talk. So let's say that this app.mailer service is should be an instance of a bundle mailer. Let's say now that I'd like to wrap this mailer with my own mailer, another one. So some decorating mailer. So this is using the decoration design pattern and the decoration design pattern is a pattern where you have a class. So let's say the decorated one, the app.mailer and you create a new class. So decorating mailer which takes the decorated class as first argument to the constructor, first or any argument to the constructor and then all the call on the public interfaces and public method on the decorating mailer should be forwarded to the rapid instance that is stored inside the object. So this is really useful to catch calls to the method and do something before, something after or something instead of when you don't call the decorated object. So you can do that by using service decoration and this is not the way to do it because if you do that, you will just replace the definition. So by having the order matters. So the first line defines an app.mailer service and the second line replaces this definition. Not about decoration, just sign out. This is a way to replace services in Drupal. If you have an existing service and you'd like to change it and to have it behave differently, just take its name and create your own definition for the service, maybe by decoration but maybe by replacing it completely and you will just replace the actual object that Drupal is using. So that works for all objects and all services which means all features in Drupal which means also it can be dangerous, so be careful. So okay, the way to do decoration is using this kind of definition. So this defines a new service which is app.decoratingmailer, that's the name of the new service. This is then the class of decoratingmailer and the special key is decorates appmailer. This one takes, and this is something magic. You can configure it, but by default that's the magic. The magic is that this creates locally a service that is called app.decoratingmailer.inner. And this .inner means this is referencing the previous one, so the appmailer definition because it takes the decorates appmailer, so this is the new name, local name, for the appmailer locally. It's an alias, yes, yes, a local alias. Yeah, it's not a true alias because you can't use it from the outside. And it's the same for app.decoratingmailer. This is the name of the service, but in your code the goal of this kind of replacement is to use this definition as an app.mailer service, as the app.mailer service. So what this does internally is also replace the actual definition of the app.mailer object by this app.decoratingmailer definition, which means this app.decoratingmailer definition should be private, usually. I didn't add it on the slide, but if I were to add public false, it would be perfect because the decorating service would be just hidden from the outside and you would just have to use app.mailer, which is really only what you need. You don't need to care about how it has been, you know, decorated and this is not important from the outside. So the generated code is very easy and this is it. It's just creating our app.mailer service as a new app.decoratingmailer, which takes our new app.mailer as first argument, okay? We could have it in being injected through setters, of course, using calls, then some setter, app.decoratingmailer, inner, and so on. Drupal doesn't use that at all, I think, yet. It's quite new, so I don't think that when Drupal adopted symphony, it existed, so that's the reason why you can't do it and I'm sure Drupal will do it internally. So that wasn't the last slide. That's not the last slide, that may be the last slide with code. So now let's talk about packs. In this case, this is the way to hook into, you know, the event system in Drupal, in Drupal 8 and also in symphony. So in symphony and in Drupal, we have this event dispatcher service, which is really an instance of container aware event dispatcher, and this one, this service is the one responsible for dispatching events. Any event that happened during the request response lifecycle is handled by events, and any events trigger events. And you need a way to register your own listeners on any event. So this is the way the response listener is hooked into the event dispatcher, and the way is by using this tag, tags setting. So we have the class as usual, and we have tags, and we have a special tag which is event dispatcher. And this is by convention the name, the tag you have to add to any service you need to be injected in the event dispatcher service. How does that work? It works by using what we call a compiler pass. So a compiler pass is something that is given to the container builder, which is some bootstrapping thing at the very beginning when the container is created itself. So when the container is created, we give it a few compiler passes, and each compiler pass handle its own tags, for example. It could do other things. But there is one compiler pass that looks for all existing services that have this event subscriber tag, get them and inject them into the event dispatcher service by name. So if it won't inject them into another service, only into this event dispatcher service, it's hard-coded into the actual instance of the compiler pass that is wired at the beginning of Drupal and of Symphony. So the generated code could look like that for the event dispatcher service, so the first one. It says, okay, let's create a new container-aware event dispatcher. I didn't add the argument, but this one needs the container itself. So this is the first argument. This, that's why it's called container-aware because it needs the container to work. So we create this instance. And then, by the compiler pass, the add subscriber service method is called several times, as many times as there are services that have the event subscriber tag attached. So the first one is our response listener. In Symphony, I looked at that yesterday, there are 26 different tags. So event subscriber, cache context, I don't know them by heart. And that's the way to hook into services and check your own. Okay, then, we have all these definitions. So definitions are stored in each module. Each module comes, can come with its own, mymodule.services.yaml file, which defines exactly these kind of things. Then the build bootstrap, bootstrapping process of Drupal and same for Symphony creates this container builder. So everything is verified so that there's no mistake there. Build compiled, compiled means generating code or generating, it's not code in Drupal, it's some object that is serialized into the database. Yet, it's the same kind of thing. Optimized, which means, you know, removing private services that were not used, for example, or inlining private services that, since they can't be fetched from the outside, we can just, you know, inline them and have them write into the generated code. Dumped, so writing in the database as PHP file. Cached, of course. Because this is read once and used many times. I mean, the definition and all of that. So tags, it doesn't have to be used and all of that. So tags, it also verifies circular references because if you have a service foo that needs a service bar and if the service bar needs itself a service foo, it can't work, but still you can define this kind of thing. After I've removed parameters resolved, that's the job of the container builder very early at the very beginning of the, you know, dependency injection container creation. Okay, it's Drupalcon. Let's brew some beer. So here we have business logic. We have a brewery class. This class has a list of, you know, Irish beers. And you can give it a number using the brew method and it will just brew that number of beers, any beer, random beers. Okay, so the brew method returns and the way of, you know, number of beers. You can define this class as a service. So let's say, let's create our Irish beer brewery. It's just an instance of Irish beer brewery. So the same class we just saw. And in Drupal, we can create this kind of controller. So this is in Symphony also. This is our Irish beer controller, which, so the target is to draw a page in Drupal that just display that number of, you know, beers, brewed beers. So we have a constructor. The constructor takes by dependency injection a brewery and then we have some action, the drink beer action and it takes a number. Then it calls the brewery to get the beers. And we, this is Drupal, we, you know, return type markup and markup just drank that many beers and that kind of beers. And there's one thing missing in this. There are several, but one is, you know, the route. So the controller needs a route. So this is not to talk about routes. So I won't talk much about that. So you have a routing to map some URL to this controller and you also need a way to tell to Drupal that this controller needs the brewery because we know that because we wrote the code and we have it on screen, but Drupal, you know, at runtime it has to discover that to create this controller and to call them the drink beer method there, it needs to create a brewery. How do I create a brewery? The answer is by implementing the container injection interface or extending the controller base, which is a base controller in Drupal, which provides the interface, but which provides also many, you know, helpers. It's not mandatory at all. So in this case, I'm not using it. And at least the container injection interface defines this public static function, create, which is a factory. So this is again the factory design pattern used for creating a controller. The job of this method is to return an instance of the current class. So new self, return new self, and then we have the container at hand there. And that's the way to get the container from the controller. Then we have the container. We call the get method to get our Irish beer brewery and by the definition we just have before, the container knows how to get it. It's injected and it works. Just to finish, some pro tips. Injecting the dick, the dependency injection container itself is an anti-pattern. You should not inject the container, so the service underscore container, into your objects. They should get the brewery directly into the container. The controller and controllers in general are some kind of exception, because at some point you need to wire things, and controller is the way where it's okay to have the container. But really, you shouldn't pass from the controller. You shouldn't pass the container to your model objects, model classes. This would be an anti-pattern. Why? Because it would make your code reliance on this God object that knows everything about your features. Just inject the feature of that, the very feature, that's your model object need and so on. Avoid circular dependencies when possible. It's possible to have foo needing bar and bar needing foo. This can exist if you have, I don't know, some logger. You have a logger formatter and the logger formatter needs to get some state from the logger itself. So this need a special way and special kind of definition. In fact, this needs setter injection, because at some point you need, if you have constructor injection, you can create them at the same time. So you can create first the logger, then you can create, for example, the formatter, inject the formatter into the container, create the formatter, sorry, with the logger injected as constructor and once you have the formatter, add it with, for example, the add formatter method on the logger if it were to exist. I didn't talk about lazy services. So there is a keyword, which is lazy, as we had public false, shared false. We also have lazy. And lazy is a keyword that tells the container to generate a proxy class. So this needs a special composer package. It's not in Drupal by default, so that's why I didn't explain much on that. Yet it's a code generator that generates a code that just has exactly the same signature than the actual class you're going to decorate. And it doesn't instance yet really the object. What it does is that when any method on this object is called, then at this time it will, for example, create the database connection. So that's the way to have lazy connection, lazy connection, database connection, so without having this logic into the database handling layer. Services should be stateless, which means reusable. Stateless means you should never call a setter on any service object if you call some set method on it, except at bootstrapping step. But later on, if you call set, it means that the second call on this method, the second use of this service, will have the set inside. So that won't be the same service. And it means you would be reliant on the order, calling order. If one first call a setter, then the state has changed. And if you do these things the other way around, so set after them, you can just mess up everything. And last, the dependency injection is just a tool, not the tool. It's not the God object. Don't create your application with the container as a dependency. Just use it to wire things and to have recipes stored in one place. And that's it. Thank you. Do you have any questions? Four minutes. Hello. Can I ask, you say that it's a way of essentially removing the new keyword from everything. Is there a particular pattern for implementing repositories? If you've got like a contact repository, would you not do new contact within that? Or how would you retrieve contacts, for example? In this case, I would call new, because repositories are for data objects. And data objects are fine, because they're just data objects. They don't provide features. So repositories and factories, you could use it at that level, but you encapsulate that? Yes, exactly. Okay, thank you. If you have any questions, I'm here. Thank you.