 Started, because we have half an hour. And we have lots of fun stuff to get through. My first disclaimer is I like to be mobile, and I'm sort of stuck to this microphone. So if I'm more awkward than normal, then we'll just blame it on that. So I'm gonna say put right here instead of wandering over there and pointing at the screen. Yeah, this is gonna be very interesting, cool. So anyways, welcome to celebrate with Service Auto-Wang. I come from the symphony world, actually. So hi, my name is Ryan. I've been around Drupal for a long time. I haven't built my first site in it yet, but I know a decent bit about it because I come from the symphony world. I'm the lead of the documentation team. I work on a lot of things related to developer experience. I'm a writer for symphony casts. That's my day job. Generally, just like a symphony fan boy. I'm a husband of the much more talented and makes everything actually work in my life and our business symphony casts, Liana. She used to come to this conference, but then we had a kid. Life got more complicated, you know? So she is at home right now. But you can tweet at her and be like, hey, Liana, is the baby asleep yet? Oh, I hope so. Oh yeah, and there he is, yeah. And further to the much more charming son, Beckett, because now I have a kid and you guys are my captive audience, so I get to show you a picture and you have to sit there and look at it. I used to have multiple pictures, but it got a little out of hand. All right, so service configuration. So what we're gonna do here is we're gonna do a little bit of setup. So I wanna kind of go through a couple of bits of code here and so you can kind of get an idea of what we're building. And so this is all gonna be kind of code that is hopefully somewhat familiar, the idea behind it. So we're gonna start with we have this class. These two guys up here were in my work type yesterday, so they're gonna recognize this class. We have a class called Barista because of course we are in the land of coffee and it has a method in it called prepare a drink. You pass it an argument and it returns a string. So just imagine this is a class that you created for some reason and you're using it, who knows, various places in your code. Great, and we're inside of a custom module. All the code is gonna be inside of a custom module. Also our Barista class is a little bit more complicated than that. We needed some third, we need some service. So I've also, I'm using dependency injection here to get the config factory service. If you're not that familiar with that service, it doesn't matter. That's a service that lives in the container and so I'm using proper dependency injection, you know, adding the constructor, adding the argument to the constructor, setting it on a property. So I'm using dependency injection to get access to that service. And of course when I do this, in order to be able to use this Barista class and in order for Drupal's container to be able to pass me the config factory, I'm gonna need a services file. So I have mycoffeeshop.services.yaml at the root of my module and I have the machine ID of my service which is coffeeshop.barista. I have a class name and of course I've specified the argument. I have one argument and it is the config factory service at config.factory. So hopefully this is at least somewhat familiar to you. This is our starting point and now that we have this registered as a service, if we wanted to use it from anywhere, but for example from a controller, I can say Drupal colon colon get container, there's other ways to do it, but Drupal colon colon get container arrow get coffeeshop.barista. So I fetch that service out of the container, the container knows to pass me the config factory as the first argument and I'm able to call my prepared drink method on it. So we have one class that class is using dependency injection, it's registered as a service. This is like the very kind of traditional verbose service configuration that has kind of worked for years and years. So this is great, except that we did way too much work. I haven't done something like that, so lay it back up. If you're not familiar with using the symphony framework, I could have copy and pasted all that code into a symphony framework and it would have worked. It's exactly the same. However, I haven't written code like that for years. That has way too much work. We got tired of doing it that way, so we basically eliminated all that and I'm gonna take you guys through step by step the things that you can actually do in Drupal today to do less work than that. So the first thing is the machine ID. I'm gonna say buy to the machine ID, which might seem a little weird at first but let me show you what I mean. This is not a, there was no passed to symphony or Drupal that made this possible. This is just something you always could have done. It's not a, oh my god, highly loo your moment, it's just a slight simplification. Most of the time you only have, if you have a class, you usually register that class as a service one time. Not always, sometimes you have a class and you make like three services and you pass it like different arguments or something but that's not the normal case. You usually have a class, you register it as a service one time in the container. So if you're doing that, why not just make the service ID the class name? It's just a little bit easier to read. So if you look at our controller now, if you were looking at this six months later, it's a little bit obvious what you're getting out of the container. You don't have to go through this later of like what's that machine ID? I wonder what kind of instance that gives me. It's just like, it's probably, it doesn't have to be, but it's probably this thing unless somebody's really trying to screw with me and making the service ID something that's just wrong. So yeah, it's just a little bit easier to read. And you can even use the colon, colon class syntax. And if you're using an editor like PHP Storm, that's really easy because you would say like, Drupal colon, colon, get container, arrow, get. And then you'd be typing like B, A, R, and hit tab and it would add the use statement on top for you and then you just do colon, colon class. Okay, so even less typing, super clear what I'm getting out of the container. So yeah, so if we have just like that one class as you know, registers a service one time, we don't really need that extra layer of machine ID abstraction in the way. It also turns out, and this is something that required a patch. This is available in Drupal 8.6. This is something you can do right now. If your ID is a class name, you don't need the class key. So notice the class key is gone here because it was a little redundant before to have like this ID, which was this long thing, and then class below it, which was the exact same string. So you can just do this. It fills in the class for you. So that's kind of nice. So let's add a second service then. So this is gonna be another spot where we're gonna add a little complexity to our application. It's not anything new. I'm not showing you a new feature. So we decided we're gonna have a coffee machine which has a brew method. It doesn't have any dependencies. It doesn't have a constructor. It's just nice, boring. But we are gonna register this as a service in a second. And I'm making this coffee machine because I want to use it from within the barista class. So in the barista class, I'm adding a second constructor argument and just doing the normal dependency injection flow, setting that on a second property. And I don't show it here, but you can imagine down further in barista I'm using the coffee machine object to do something. But of course, as soon as we add a second argument to the barista class, we're gonna need to go to our services file to tell a container, hey, there's now a second argument that you need to pass to barista when you instantiate it. So that's fine. So actually reading this from the bottom first, first thing we're gonna do really is probably register our new coffee machine class as a service. We're gonna use our new kind of class name instead of the machine ID way of doing that. It has no arguments, that's easy. And then up above here, I'm just gonna say at and then the long class name. So to register that, or to tell a container that needs to pass that. Cool? All right, so nothing new there, but we have a little bit of extra complexity. So now let's talk about auto-wiring. This is another feature that is available already in Drupal today. So with auto-wiring, it's an option that you can pass under your service. So normally you just have class and arguments. If you say auto-wire are true, you can take off the arguments. The arguments can be empty. Because Drupal's gonna figure out what you want to pass there. And the way it does that is by reading the type hints. So yeah, this is not gonna work if you have a scalar argument, like a string or something, and we're gonna talk about how you handle that later. But most of the time you're doing auto-wiring, you're doing dependency injection because you need another service. So if you do the type hint, then it's gonna get automatically passed to you. Now, key question is how does that work? And the answer is it depends. There's actually, and we're gonna talk about this later, but there's actually two different ways, there's two different pieces of logic in Drupal and Symphony that do this. There's the old logic, which still works in Drupal 8.6, and there's the new way of doing it. So the old way of doing it, which at this moment is what we're using. The old way of doing it was basically when you had auto-wire true for a service, it looked at your type hint, looks at all the services in the container, and if one of the services in the container implements that interface or has that class, you can use interface or class, if it finds exactly one that matches that, it passes it to you. If it finds zero or two, then you get an error. That's what makes sense. It was actually a little bit too magical for us, so there's actually a newer way of doing auto-wiring, like a new strategy that's a little bit more explicit, a little more, where you actually kind of control it more, and I'm gonna talk about that later. But right now it's actually like going through and just saying, yeah, I see that there's one service in the container that implements the config factory interface, so probably that's what you want. And same thing, obviously with Coffee Machine, there's only one service with Coffee Machine, so it just passes the Coffee Machine to us. So it means that our services file is starting to get skinny, starting to just be the class names, and that's it. So the next thing that we can do is apply some default service configuration, because I don't have it here, but our Coffee Machine doesn't have any arguments yet, but probably we're gonna wanna have auto-wire under all of our services, so that way if we have auto-wire under our Coffee Machine service, it's gonna allow us to just go into that class, add a constructor argument, type in it, and just keep working. Not need to go back to my services file and add auto-wire or wire up the argument explicitly. So we're probably gonna want auto-wire under everything. Auto-wiring only fills in your missing arguments. So if you have auto-wire true under something and for some reason you decided to tell the container all of the constructor arguments, auto-wire gives a big shoulder shrug. It's like, eh, looks like you already did the work. So it's actually safe to have auto-wire on all the time, and it's only gonna try to fill in the stuff that you're missing anyways. So default service config, how can we just say like, look, when I register services, just make them all auto-wire without meaning to say auto-wire true, auto-wire true, auto-wire true. And you actually can, small lie, do that by adding this magic underscore defaults key. This is a new feature that's coming from Symphony. Underscore defaults is like a magic service ID here, so it is a specific magic string. And any configuration you put under underscore defaults is going to apply to every service in this file. It's kind of this great global slash local configuration. It's not gonna modify services coming from Core or coming from some contrib module. It's only gonna apply to what you actually have in this file, so it's really, really nice. So if we do this, that's a small improvement. We're able to get rid of auto-wire true under one service. If we had 10 services, that would actually save just like 10 lines of code. That's cool, I like that. So let's take this a step further, and this is where things really start to get bananas. Service auto-registration. Because it's kind of, we're starting to see a pattern here. Like every class I put in my service directory, and I just made that up, I often at times have a service directory. I'm always registering them as a service. And I'm always using the class name as the service ID. And you're like, can't that maybe be automated a little bit? And the answer is actually yes. So with this syntax here, where you actually have, it sort of looks like a service, but it has this resource key under it. You actually kind of put the namespace prefix of what you kind of expect to be in that directory, and this can go recursive, this can look at multiple subdirectories. Basically it says, look at my service directory. And by the way, that resource is a glob pattern, so you can actually say like, look in this directory, and this directory, and this directory, and match star dot this, or anything like that. There's also an exclude key, so you can say like, look, use this pattern in these directories, but exclude this one directory and this other directory. So you can use whatever kind of pattern you want to kind of locate where your service classes are. Because then not everything in your source directory is actually a service. But the stuff that is, you want to kind of capture it with this. So this does literally just goes and finds those, and registers them as a service automatically for you. And because you have that autowire under the underscore defaults, they're all being registered with no options, but that autowire under from defaults is actually being applied to them because they are being registered in this file. So suddenly we have the exact same thing that we had before, just with no lines of, just without actually having to do any work. So this is really like the game changing thing because if you think about how it's going to look going forward in our module, if I need to create a new service and start using it, I'm going to touch no config. I'm going to create a class in my service directory and it's immediately available to you somewhere because it's automatically registered as a service. If I'm inside of a service and I decide I need a third constructor argument, I add a third constructor argument, I type in to it with the thing I need and I keep coding. I don't go to a YAML file. This is a big change we kind of introduced. It's actually available in symphony 3.4, which is why it's in Drupalapse. But this is a big push for us in symphony 4. We want to keep you inside your code, not constantly switching context to go back to the framework Drupal kind of integration configuration level, like stay in your code and keep coding. So this is wonderful, except that it doesn't work. The problem is it's one of those weird cases where the code for this actually exists in Drupal, but they overwrote it. And so basically it's like an, it says a class in the core of Drupal that's basically out of date. There is an open issue tracker. You can find it if you Google for it about auto wiring and this basically needs to be enabled. However, I'm gonna give you a very quick workaround because this is actually very easy to re-add yourselves. So this stuff doesn't work out. I hope it will work soon. It's not a big deal. I just basically need to say like bring the new code kind of downstream and that it's gonna work. So let's build it ourselves. So you might not be familiar with this concept. You'll see it in lots of contrib modules. If you wanna really do some custom service configuration stuff then you can create what's called a service provider. You just basically create a class that lives directly in the source directory of your Drupal module and it needs to have, you call it like module name service provider. It needs to implement the service provider interface. So it's one of those cases where you like name something exactly right and Drupal finds it. One of those situations. So if you follow those rules then when the container is being built it's gonna call this register function and you can do whatever you want inside of here. So here's what we're gonna do. We are gonna basically re-add that functionality in about 12 lines of code. So we're gonna use a class called finder. This comes from Symphony but it's available in Drupal projects automatically. It's just a nice way to kind of find files. So we can say hey find everything in the service directory that ends in start.php and then we can loop over it. Then we can say the class name is gonna be Drupal slash coffee shop slash service slash and then we're gonna grab the full name and just strip off the .php. Kind of a dirty little thing but this works great. We're just getting the class name because we know it has to follow those rules. So to kind of continue on that for each. Okay now that we have this class name. So this is our kind of the just looking at the for each. We have the class name and by the way this container builder thing this is a little bit more advanced. This is an object that helps build the services in the container. So basically what we do is we ask the container has definition as a way of asking is this service already exist in the container yes or no? And if it does we're just going to skip it. And the reason why and you'll see this in a second is this is gonna allow us to actually explicitly set these services in our services.yaml file and then if we decided to do that we skip it here because this is actually run after our services.yaml files loaded. What we don't want to do is like do a bunch of like have a situation where we actually do need to do some really custom configuration. We put it in our services.yaml file and then this thing overrides it and kills all of our kind of custom settings. So this is basically saying if the user's already registered this service then like we're good just like use theirs. So we're skipping it. And then the last part here is this is basically on a PHP level how you register services. You don't do this that often but you create this thing called a definition. You pass it to the class. We're gonna set our way to true that kind of takes care of our underscore defaults thing or we set our way to turn everything and then we're gonna set that into the container. So with those 12-ish lines of code we now have everything in our service directory auto registered as a service and it's all set to auto wire. Which means that your services.yaml file now becomes the most boring file that you have in your application. There's literally nothing here. Yes. So there's two other things. All right good we're doing perfect on time. This is and I promise everything else I'm gonna show you is it actually works. There's no more like and it doesn't work. So those are the only 12 lines of code that you kind of need to hack in your module right now to get it to work. So another thing that is available right now and actually works I promise is something called named arguments. I love this feature. So let's go back to something I mentioned earlier which is this auto wiring thing is all well and good as long as what you are trying to get is actually a service. Something that actually has a class with a type in. So if you have some sort of configuration API key I don't know database credentials or something like that that you wanna pass in like auto wiring is not gonna work. So I'm passing in the number of scoops that I should use in my coffee here. It's an integer. I use scale of type ining but that doesn't help. The container has no idea what to pass there. So if we do this and try to rebuild our cache we're gonna get this actually really nice error. Can an auto wire service coffee machine argument number of scoops of method construct is type hinted int you should configure its value explicitly. Okay, I don't know what to pass you. And this is one of the really nice things about auto wiring in general is like all of your services are like when you do a container rebuild or a cache rebuild all of your services are basically validated. If you have any even one spot where there's one argument where it can't figure out what to do with it even if it's not on it's on some edge case page that you even forgot that somebody built five years ago you're not gonna be able to rebuild your cache at all if you have one mistake. So there's no like secret weird edge case thing you didn't realize was broken because you may be removed a service and it was being auto wired somewhere that you forgot about. It's definitely very, yeah. I can tell you confidently because we've been doing this in Symphony for years like this works great. You do not have like the WTF moments that you would imagine that you would have from kind of this auto wiring stuff. So this is easy enough. Basically when you get into this situation it means that you are gonna have to explicitly configure your service. Now this is not the best example but what I want you to imagine here is that imagine that we do have this number of scoops argument but imagine that the second argument we actually have a second argument here which is something we can auto wire. Or maybe the other way around maybe the first argument is something we can auto wire but the second argument is this int. So you're like dang it. So now you're telling me like as soon as I need to specify one argument I have to basically scrap the whole thing and kind of go back to the drawing board and specify all my arguments. Because remember arguments that the way we normally specify arguments is by order. Like arguments colon and then you have like your first argument comma second argument comma third argument. So noun arguments is something you can do. I love named arguments. This literally binds to the name of your argument which means you can have five constructor arguments. One of them can't be auto wired and so you just specify that one. Now this is a bit of a weird case here because normally if you decided inside of your coffee machine class down there on the bottom, if you decided that you wanted to rename that argument, you could normally do that without any outside side effects, right? Like if you just renamed an argument to something it's still the first argument so anybody passing you that is gonna work fine. So it is a little bit weird that if we renamed that right now to like num of scoops or something like that our application would actually break because it's not bound to that argument anymore. However, again, the way it's gonna break is if you try to rebuild your container at all you're gonna get an error that says the service coffee machine has an argument called number of scoops in the YAML file but we couldn't find that in your constructor. You're probably doing something wrong. So if it can't match that up then you're gonna get an error. Or if we took off the number of scoops entirely it's gonna tell you that we can't auto wire it. It's been the same errors before it's gonna say that we can't auto wire it. So it's actually very hard to screw this up without knowing that you screwed something up. So the last thing I wanna talk about is that I mentioned earlier is the new way of doing auto wiring. So I mentioned the logic before is that you add a type int and it just looks across all the services and tries to find exactly one that matches that type int. So the truth is actually the in Drupal 8.6 both the old logic and the new logic are available and they're kind of working together. The new logic which I'm going to explain right now is actually what takes precedence but if it fails then the old logic takes over and tries to fill in. Then tries to like scan over all the services and find something that actually matches. So if you want to, because this would basically kind of prepare you for Drupal 9 when you move to Symphony 4 and the old way is not available anymore. If you want to you can actually turn off the old way. So you can have this special parameter here which basically says I want to use the new way of auto wiring. Don't use that old magical way of scanning every service and looking to see if it implements the right interface or it has the right class. Okay, as soon as we do that we're going to get this error. Again it's a really nice error. It says, can all our service Barista argument config factory references the interface config factory interface but no such service exists. You should maybe alias this interface to the existing config.factory service. Gosh, I love that error. So the way that auto wiring works now is it's so dumb, I love it. When you have a type int like, you know, Drupal slash core slash config slash config factory interface the auto wiring system looks in the container to see if there is a service whose machine ID equals that string exactly. So there's no scanning everything. It's just like going to look in the container and say, hey is there a service in the container called Drupal slash core slash config slash config factory interface. Yes or no. So the way that you chew is the way you kind of configure like, hey this interface should give me this service is you create something called a service alias which is something that's existed forever in symphony but it hasn't really been that important until now. It's basically a symbiote link. You can say, hey, it has nothing to do with auto wiring. You can say, hey, when somebody asks for the service called foo wire I want actually you to give them that service. But we can leverage it here because we can say, hey, whenever somebody asks for the service Drupal slash core slash config slash config factory service I actually want you to give them the config that factory service. And now the auto wiring system looks in the container and it goes, oh my gosh, there is a service in the container called Drupal slash core slash config slash config factory interface. So I'm gonna auto wire that. And the error message is telling you that. So the error message actually looked in the container and said, no, I don't see anything like that in the container. But then in order to create this error message it actually looked at all of the services determine that one of them does in fact implement this interface and kind of gives you this hint. It was like, I don't see this class in the container. But by the way, I did find one that implements the interface. Maybe you should create an alias to it. Or if there are three of them, you'd actually see like maybe you should create an alias to one of these three services. So it actually helps you out. By the way, our coffee machine class we're also using auto wiring for our own coffee machine class. Or remember when we use the auto registration or more generally when we use our class names as our machine IDs, that means all of our classes are instantly auto wireable. Because there is really a service in the container called Drupal slash coffee machine slash service slash so I copy top slash service slash coffee machine. That's the service ID. So all of our stuff is just gonna auto wire instantly without doing anything. So this is what an alias looks like. Drupal slash core slash config slash config factor interface instead of like class and arguments so you just say alias config dot factory. Now, ideally, core would do this for us. Ideally core, this is actually what happens in symphony. Core would say we actually want to empower people to use auto wiring if they choose to. So for all of the services that we deem like normally usable by our end users we're gonna go ahead and add these aliases for them so that they can just like auto wire them into their application. And this is something that I hope kind of along with that issue tracker, I think that's one of the things that they need to do if they want to do this. It could even be a contrib module that you bring in that basically adds all these auto wiring aliases for all the core stuff. Doesn't add any extra overhead or anything like that. So it's just something that they need to do to make your life easier because there's really no reason that we need to do this for all the core stuff. So you do need to do it now for auto wiring core stuff and then you do it one time and then you can always auto wire this config factor interface anywhere. And as you guys saw, you get really nice error if it's not there already. So let's summarize here. Number one, use class names as your service IDs because it just makes life easier. You can stop right there, that would just make your application a little bit cooler. Second, use auto wire true and start being lazy and omitting your arguments. Cool. Three and four, you know, wait for Drupal to support this slash, take my 12 lines of like hacky code and do service auto registration. Automatically register this directory, that directory and that directory. However you organize your code into services in your module, auto register those things as services. And then if I specify any non-autowireable arguments, the stuff that falls through the cracks, specify those with the named arguments. And six, and if you recommend doing this or, you know, doing this down the road at some point, you know, once you kind of get used to this because it is going to make you do a little bit more work to use this, turn off the magic auto wiring. It's just easier to think about. You're never going to be any question about like what you're going to get because you're going to be in complete control of how auto wiring works. And yeah, that's it. Thank you guys very much. And I do have the code on the bottom there, the bit.ly slash Drupal dot auto wiring dot code. That's going to, it's a link to GitHub that has like the clean, everything we did, clean step by step by step by step. So you can actually see what I did and walked through and grabbed my like 15 lines of hacky code. Also I come from the symphony world, so I have to do a plug for symphony cast tutorial if you want to learn symphony or go check that out there. Questions. When I was alicing the config factory, can I alias the, ask that last part again? Like right there? Yeah, I like not the interface. Yeah, totally. So I could have also alias Drupal slash core slash config slash config factory to config that factory, yep. And in the symphony world, because we like try to like gently push people towards interface type printing, we don't do that. But like on a technical level, yeah, absolutely you can do that. If you wanted to make things more friendly, you'd probably like alias both of them, you know. Yep, question. You could have set a default value in the constructor. Are you kind of thinking the, like this thing? Number of scoops? So yeah, so yeah, you could, yeah. So the thing is, could you just give me the default value in the constructor and the answer is absolutely. But you're gonna get lots of cases where you can't do that because what it actually is is like an API key. With number of scoops, you're sort of like, I'm gonna have like a number of scoops default value to three. And I could override it if I wanted to, but most of the time I don't. But we have other cases where it's like a database credentials or API key or something, something like that where like, you really do need to kind of like pass it in. You know, maybe you're like reading it from somewhere that's not committed from a secrets place or something like that. Yeah, totally. If we had given a default value, we would not need to specify it because the container doesn't need to pass it. Yep, amen. So assuming we went through and did this, do we still need a blank services.yaml file? Like, does it have? Yeah, yeah, yeah, yeah, so if we did all this, do we need a blank services.yaml file? The answer is no. You'd actually not need any services.yaml file. Until you need to specify that one argument that can't be auto-wired, then you'll create it. So you probably in practice will have one. And in the future once that like auto registration and defaults thing makes it back to Drupal, then your service.yaml file will always exist because you'll at least have like those four lines of code. I'm auto-wiring all my things by default and I'm doing my service auto registration for this directory. So like in a normal symphony project, when we started a new symphony project, our services.yaml file has like those five lines of code. And you might actually code quite a bit before you actually ever need to go back and do anything else in that file. But it's just kind of like sitting there activating the magic, but not doing anything else. Yep. It seemed like your workaround solution was meant to be contributed to each, or meant to be written in each module. Is there a way to abstract that at one more level? So there's only like one thing to remove when it gets into Drupal. Yeah, good question, yeah. Cause like my workaround hack was something that was like specific to that module. So you'd have to have that stuff like in every single specific module. How would you abstract that? I'm trying, there's an easy answer that's kind of cheaty and then there's a different answer. Cause technically there's nothing stopping you from having like five modules and having that one class in one module, which is also registering the services for your other five modules. You know what I mean? Which is what you're like, oh, that's not exactly what I wanted. So you're gonna have to, if you want to actually keep them separate, you're gonna have to have that service provider in all of your individual modules. No, they can actually like, I'll talk to maybe like one core module that they're dependent on, which has like the bulk of the logic. But unfortunately, like, yeah, you have to have that in the separate places right now. Until we get that workaround. Right, until we don't have to have that workaround I should say. Yep, any other questions? Yeah, in practice, like if you've got your interfaces in the same folder as your services, which isn't unusual, right? And how would you just target the services rather than the interface? Oh man, that's such a good question. He's also, if I'm in my own module and I have like in my service director or some services, but I'm also creating my own interfaces that my services implement, that would be something to give you two answers to that. Right now you'd have to do a little bit of like extra logic in that glue code. You know, I'd have to say like, and maybe if you suffix everything with interface, then like, you know, skip over those ones in the for each loop or actually like look at the, you know, once you get the class, you can actually do a class exists or an interface exists to see if it's an interface or it's a class. So you're basically gonna have to put that in your workaround. Once the feature gets back into Drupal though, that already works out of the box with the actual auto registration feature. When the actual auto registration feature from Symphony when it goes over that service directory, for example, if it finds something that's an interface and it finds only one thing inside of that directory that implements that interface, it automatically adds an alias for the interface that points to your service. So it means that you can actually just create a service and create an interface and you know, make your service implement that interface and instantly start going to other parts of your code and type inting the interface and getting your actual concrete class because it makes that mapping for you. So again, in the future, even easier. Yep. Yeah, so the auto registration feature in Symphony, when you're not having to do the workaround, if it, let's say it looks at your source directory and it sees like a coffee shop class, but it also sees that you have a coffee shop interface. And of course the coffee shop class implements the coffee shop interface. And this is an interface you created just because you want to have interfaces. What Symphony is going to do is it's going to automatically register your coffee shop class as a service. But then it's also going to see that coffee shop interface and it's going to see that you only have one class that implements that. So this doesn't happen if you had like two different classes that both implement the interface. But because there's only one coffee shop class that implements that interface, so it's going to register a coffee shop as a service and then it's going to register the coffee shop interface as a service alias that points to your coffee shop class. So you actually end up with kind of two things in the container. You end up with the coffee shop class and then you have the coffee shop interface which is not a real service but just an alias to your coffee shop class. The end result is that you create the class, you create the interface and then you immediately go somewhere else and you type in the interface in your constructor and it just works. It knows to get your concrete class. You don't have to add like an extra wiring to say this interface points to this class. Yeah, really good question. Cool, awesome. If you guys have more questions, go ahead one more and I'll let you go. So assuming someone here was going to contribute this back to Drupal Core or a Contrib module, is there a way to mark the old aliases as deprecated? Oh man, what do you mean the old aliases as deprecated? So like a config.factory, right? Theoretically we should stop using that and go to the class name. Good question. So you should not stop using config.factory because there might still be cases where like, well this is how we do it in the Symphony World. We still use the snake case machine names for our services and we might have like 200 services and then we decide about 100 of those are actually services that really are meant to be used by the users day in and day out and so we had aliases for those 100. But the other 100 you can't actually get unless you actually use the old snake case version. It's way for us to kind of say, hey I realize there's 200 services here. You can use all of them because you could just, you know, do old school registration of your arguments and use all of them. But these are probably the 100 you want to use because we think that they're more common. The other thing is that with contrib modules, you should not use auto-wine with contrib modules. It adds a slight performance overhead during development only, during cash rebuild only. But if you're doing like a proper, you know, contrib module like explicitly do everything so that you don't add that little extra overhead like, sorry, if you're doing a contrib module, you need to do things like the slow boring way so that the people that use your contrib module have like a little bit of an easier life. Now more broadly though, there is a feature in Symphony, so a feature in Drupal to deprecate services. It's something you're probably gonna start saying as Drupal 8 gets closer to Drupal 9. It's actually a key, you can put up all your services that say deprecated true. And if anybody uses that, then it shows us it's deprecated. It's not available right now, but in a newer version of Symphony, you can also deprecate aliases. Yep. Sorry, one more question. I haven't wrapped my head around all the potentially cases of this, but isn't using the class name as the service ID kind of getting us back to a singleton pattern? Yeah, you do. Services, sorry, is using the class name as the service ID getting us back to the singleton pattern. In a container world, our services are singletons. Now they're not singletons because we're not actually using the static context. What's bad about singletons is they rely on the static context to actually guarantee that there's only one thing in there. But we actually, in reality with services, we actually only want most of the time one instance of a service hanging around. But we don't want to use singletons. So you're like, oh, what do we do? That's why the container exists. So we can get the goodness of singletons. We don't need 10 coffee machines services. We need one coffee machine service and we'll call the method on it 10 times. So we want that singleton thing. We don't want the singleton pattern. The container is what allows us to do that. So that service isn't testing then since purchase? Yeah, the cool thing about all this auto-wiring stuff is that if you wrote your classes using dependency injection and type-hinting interfaces, like if you did best practice of kind of designing your services and then you changed your entire application to use auto-wiring and you did a pull request, you'd notice that you didn't touch any of your PHP classes. This is all configuration based. Yeah, so your classes are all still written. In fact, it nudges you towards doing things correctly because if you don't add a type-hint, darn it, you don't get auto-wiring. That's annoying. So now I'm gonna add the type-hint so I get it. Like I said, in symphony we add the auto-wiring aliases only for the interfaces to really nudge you to, you know, and if you do it like if you add a type-hint for a concrete class, but only the aliases for the interface exists, you're gonna get an ali that says I didn't find this in the container, but I did notice that there's another service that this class you try to type in with implements, did you maybe mean to use that type-hint instead of the concrete class? You'll get a real quick error. Yep. All right, cool. So now we have our courses coming up. Thank you guys very much. It was awesome. Thank you. Thank you. Thank you.