Started, because we have half an hour. And we have lots of fun stuff to get through.  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.  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.  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.  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.  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.  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.  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.  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.


What's going on, everyone? Sam here with Layton Sportsguards, ripping 2022 top scrim black baseball, hobby 12 box, case break number 22. Pick your team style, got a list of our names and teams in front of me. Gonna read them off really quick. We've got Andrew G, athletics Cardinals, Bowies, Astros, Brian F. Orioles, Christopher G. Metz, Corey A with the Diamond Bax Marlins. Thank you, Corey. Daniel U, Nationals, Edward L. Mariners, Hyun Q. I with the Tigers, Jared V. Red Sox, Jesse K. Yankee's Pirates, Jonathan B with the White Sox, Jonathan Q. with the Reds, Joshua J. Guardian's Dodgers, Twins and Giants, Larry V. Blue J's, Lawrence K. Rangers, Long J. Brewers, Michael V. Phillies, Mike A. Braves, Nathan H. Royals, Noah H. Cubs, Robert S. Rockies, and Padres, Shanichi S. with the Angels, and Stephen N. with the Rays. Good luck, everybody. Let's do it. Top show in black time. Full super. Lincoln Bio. This is a group break right here, Rab. Link is in the bio if you'd like to join. Acuña, JD. There's Max Scherzer refractor to 199 for the Metz. First auto of the break is going to be going to the Metz. That's Daryl Strawberry. Congrats, New York. There you go. We'll take that. Metz is going to be Christopher G. Congrats, Christopher. Nice, Strawberry. On to the next one here, guys. Good luck. Cedric Mullins, Joe Adelves, and Green. Jazz Chisholm for the Marlins, 13 out of 99. Gratz, the Fish. Got a gold auto coming up here. Going to the Metz again. Peter Lanzo, 45 out of 50. There we go. Christopher G is sweeping the hits right now. Nice gold. It's true gold of Alonzo as well. We'll take that, Fuller Bear. Remember I called Peter Lanzo overrated? Like, on one of the release days, and Forest was like, and how is Peter Lanzo overrated? And I'm like, I don't know, Forest. I'm just a hater, dude. Like, let me hate in peace. I'm just a bad guy, man. Louis Heal. O'Neal Cruz, Variation Rookie. And Orange, Starling Marte, 13 out of 25. Going to the Metz. Nice one there. Color match. We've got a Alex Kirolov base auto. That's going to the twins. Gratz, twins not numbered. No T-Law in this, I don't believe. Probably not going to be a trouble on this auto coming out of this. No T-Law? No, unfortunately. Now, we don't really sell singles, Will. We have a shop in Apopka, Florida. That's where we sell most of our singles, but not on stream. Dude, the Metz are just killing it, dude. That's unreal. Vidal Bruhan Rookie. Braxton Stott Rookie. Gold Francisco Lindor. 24 out of 50. Dude, they're just killing it, man, with the colored stuff. We've got next auto is Blue Jays, Alex Minoa. Gratz, Toronto. Toronto is Larry V. There you go, Larry. Nice Minoa auto for you, man. He's good. I like Minoa a lot. This sucks, he's in our division. Corbin Burns. Blue Hunter Green. Nice one there to 150. No, to 75. Just kidding. And how about Yankees, Legend, Andrew Benintendi? 21 out of 150 for the Yankees. All right, we got Refractor Auto. Raleigh Fingers. 59 out of 150. Nice one there for Oakland. Gratz A's. All facial hair team on spots. Nice. Some more triple thread spots are coming in. Thank you guys. Thank you. Thank you. Thank you. Adam P. Joshua J. Jonathan Q. Jordan W. Taking some spots. Michael H. Taking some spots. Victor F. Taking some spots. Thank you guys. We're slowly but surely making our way down on those triple threads breaks. Again, TikTok. Link in bio if you'd like to join group breaks. Link is in bio. We still have some spots. All baseball today. Still have some spots. The top's triple threads. Nine box, half casers. Hell yeah, Ramos. Rookie. Jonathan Nindia. And Reed Detmer's to 199 on the Refractor Rookie for the Angels. Got a green coming up here. It's going to be Tre Mancini. 92 out of 99. Going to the Orioles. Nice one there. Baltimore. I think that's Bryan F. If I'm not mistaken. That is Bryan F. There you go, Bryan. Congrats, buddy. Nice Mancini coming your way. Matt Olson. Josh Donaldson. Refractor. Brian Hayes to 199. Got a Joey Vado. Nice one there for the Reds. Jonathan Q. I'm going to say that is. Yes it is. There you go, Jonathan. Nice Vado. One of the Reds' best players in the last 20 years. Probably their best player in the last 20 years. Shane Bob's Rookie. Juan Soto as a Padre. There's Gavin Sheetz. 77 out of 99. Rookie for the White Sox. And we've got Rookie Otto at Ryan Vallade. Going to the Rockies. Congrats, Colorado. Nice V-Lade. Lettix gone. Orioles gone. Thank you guys. Spots are coming in fast and furious now. Appreciate y'all. Call us to the Vin Diesel movie. They're coming in fast and furious. I know love on that one. Come on. What did you say? Oh, I know. Friday La Cruz, Rookie. Purple Andrew Vaughn to 154 at the White Sox. We've got Brew Crew Robin Yell. There we go, Milwaukee. Nice one there. Milwaukee in the last two cases done very well. Picked up a Cutch last case. Now we got a Yell in this case. Well, I believe Long J has both of them. Brewers in both cases. There you go, Long.  It'll be fun. Oh, Lakes on TikTok. Appreciate y'all. Joby Peña, Rookie. Joby Bart. An orange. Mandy Machado. That's pretty sick. Going to the Padres. Five out of 25. Nice one there. And going to the Cubs. Ryan Sandberg. Nice Rhino. Chicago. Noah H. There you go, Noah. Congrats, buddy. Two boxes to go. Got him. Sheets, Rookie. Andrew Vaughn base. And Jake Burger. Refractor at a 199. White Sox pack right there. Gold auto. Is a Ted Simmons. Nice one there. Four out of 50 on the Gold Mini Diamonds for the Cardinals. Nice hit for St. Louis. That is Andrew G. There you go, Andrew. Congrats, buddy. Ted Simmons. Love the Gold Mini Diamonds. And last box of the case. Good luck, guys. See what we got here, y'all. Got an orange auto. It looks like very nice. We'll take that. Take that. Ended on an orange auto. Yes, you were right. I think it's a second time in a row we want gold and orange auto. Back to back. Andrew Benentendi. Rookie of Aaron Ashby for the Brew Crew. And Purple. Aaron Ashby for the Brewers. 150. Mini Diamonds. And we've got, that's going to Chicago. Seven out of 25. Super futures, Andrew Vaughn. Nice one there. Congrats, Chicago. Most throwback White Sox jerseys. That will do it for the break, guys. Thanks again for the fill. No recap on this. Everything is a hit. Next up, we've got our case.


So this is just a quick video on a couple of methods for attaching a motorbike alternator onto a bicycle wheel hub. Motorbike alternators are reasonably good for use with wind and water turbines. They'll do reasonable amount of power, reasonably good voltage per rpm. The very good thing about them is that they're very available in a lot of parts of the world. So pretty much anywhere you can get one of these. The main drawback is that they don't come with bearings like the when you take them off the bike or the scooter or the tuk-tuk or like or whatever. They're basically it's gonna be like a rotor and a stator separate. So you'll need to mount them to each other in some way that they can spin easily and happily. And the best way I've found for that is just using a bicycle wheel hub. These will do, I mean, about two, three, four hundred watts maximum output and and about 15 volts AC per 1000 rpm, which is okay. It's better than most options. I can't think of a better option or even really a second option in places where you're not going to find mass produced like consumer grade items. You will need to gear them up for vertical axis wind turbines by a factor of about 10. For horizontal axis two or three. For hydro turbines, though, they should be able to direct drive. They should be able to do 12-volt battery charge voltage coupled on to a palatable wheel. I'm going to be putting one on my siphon turbine design. So as it is, when you take this off a motorbike, you'll have the stator with the coils and you'll have the rotor with the magnets and they won't, they're not mounted on each other. So they'll need to be put on a bearing in order to, well, you know, for obvious reasons. So it's just a matter of chucking the stator onto the front of that, the hub and then chucking the rotor onto the axle and then that will then spin freely. So you'll want a wheel which is not a quick release. You'll want a solid axle about 10 millimeters. That's standard. So the first thing you'll want to do is just cut your bike wheel hub out of the wheel. You can use tin snips. You can use side cutters, an angle grinder, bolt cutters, basically anything which will just go through these spokes. Doesn't take much. You'll want to cut them fairly close down towards the base. It just makes it easier to get the little bits out afterwards. We end up with that. And then just take all of these little guys out of there. So then you're going to want to open this up, give it a bit of a clean and a grease if it needs it. And also, most importantly, wind this axle on one side out. Basically as far as it'll go, because that'll give you your room to attach this guy on here. So for that, you will want to have a biker cone spanner that's to fit into the little cone nuts that are here. Anything like 15 or 13 millimeter spanner, which is really thin. It'll need to look super thin down there. We'll go on there, but nothing else will. So you will need that. That's just a matter of chucking spanner to cone nuts. And a spanner to lock nuts on.  Be careful when you open this up, because if the bearings are not encapsulated, if they're just in there and they don't have like a housing around them, then they can fall out. And you do not want to hear the sound of a dozen little ball bearings falling to the ground and never being found again. This wheel is fairly clean and well greased.  Now get it so it's a little bit loose, a little bit wobbly, and then just tighten these outer nuts together until it's sort of nice, run smooth, doesn't wobble. But so then you've got that, like wheel hub with all the thread on one side. You'll then want to mount your stator, this guy, on to here. Each stator is different. They'll have different holes available, different number of poles and stuff. This one has two opposing holes. So basically it's going to drill out to opposite side holes that the spokes were in, and putting in these M5 bolts. I'm using socket head bolts, because the head fits a bit easier on here and is also just what I have available, but pretty much anything there will work. They can also be M3, M4 bolts. You might, as in this case, want to cut out a bit just where it's hitting on the earth. Tag there. Just hacksaw or angle grinder or file or anything will do it. And then because this is just an aluminium hub, let's just snap these bits off. Basically that just slots directly onto there. So the head fits fairly nicely inside there. Using nylocs, lock nuts. So the stator needs to be very nicely centered on the hub, but that's fairly easy to do because if your bolts are symmetrical, then it should just pull it to center, essentially. If the holes here are not quite so nicely symmetrical, then you might need to adjust the amount of pull that you put on your bolts. Again, this is kind of easy to get right and hard to get wrong, but you do want this nice and good because the tolerances in here are fairly tight. Once this is spinning, you obviously don't want it rubbing anywhere. So just take a second to get things nice and centered. So that there now is the stator mounted on the bike wheel. So I like to use one of these kinds of nuts. So like the lock nut that was on it was that fairly typical kind of lock nut. You can sort of see on the same on the other side there. But on the outside of the forks on the bike, they usually lock it off with one of these guys. I like to put that on that side there because the inside hub of the rotor is slightly conical and usually is a good size that it nicely fits onto that nut there and basically centers itself. So as you wind that on there, it will naturally find its way to center. It will also to an extent with these lock nuts just because they're slightly domed and the same sort of effect will happen. But I mean, your wheel is almost certainly going to have one or two of these on it anyway. It sort of fits a bit nicer and just sort of sits a bit nicer. So now when we place the rotor onto here, it will sit nicely onto that nut and all the clearances around here should be good if this is centered. It should work out that the up-down of this should work out as well. If not, if this is sitting too high or too low and your coils aren't quite in the middle there, you can pack out that with washers or use a thinner nut if it's too far out already. But it should basically just sit there nicely. And then just a matter of taking some washers onto the back here. Check another lock nut on. But you want to get that nut on like basically as tight as you can get it. Because otherwise that might slip. You can maybe try keying this, but if you get it like good and tight, it shouldn't slip. And so then you can see that that is now spinning nicely in there. Not rubbing on anything. Nicely centered. And that's it. That's now mounted on there in such a way that you can now use this as an alternator in a turbine. So then the obvious question is how do you then spin your rotor? How do you attach this to your wind turbine or your water turbine or whatever you're plugging it into? Probably the best way, depending on your setup, is just to attach an automotive pulley to it. So this is just off the alternator of a car, which I've also got a two and a half meter loop, longitudinally grooved belt. So the belt will attach around the turbine and then attach to the pulley here. And then as that turns, it turns the rotor. So you'll want to mount your rotor with quite a bit of thread off the other side. We're going to be attaching the pulley. Luckily, I'm not sure if this is standard, but with mine, one of these standard 10 mil bike nuts, which fit a 15 mil spanner, happened to nest pretty much perfectly in there, in the bottom hole, which means that it'll center that really nicely. So it's just a matter of winding that nut onto the back end of your thread. So here I've obviously taken these pockets set off this wheel, so just get in the way otherwise. Getting that pretty good and tight. And then just mounting that on there and locking it down with another nut. If you have enough thread off this end, you can mount the spacing down, and that will then shift the lever force of the belt just a little bit closer into the bearing, which can be nice depending how much force you're putting through this. It's probably not necessary, but if you can, it's a little bit better. You can also have the thread coming out on this side and attach this guy here using exactly the same method, which, again, is not quite so ideal, I think, because, again, it's moving the force out away quite a bit. So you're going to get more of a lever force on your bearings. So having it on this side just means that your force is then balanced a bit more across the whole thing. So just lock that down, good and tight. Like this is not slipping because of how tight you're going to get this attachment. So you might want to even like put this in a vice or something and then just like really lean on it so that it cannot possibly slip. And then you've got that assembly there. So you then loop your belt around here. You have a tensioner pulley. It will go on to another, like probably larger pulley on your turbine, or if you're doing the $30 wind turbine design onto the bike wheel itself, which then acts as like a 60 centimeter pulley so you get like almost like a 12 to 1, 10 to 1 gearing onto here. And then as that turns, you have this mounted onto your pole or your turbine assembly in such a way that the bike wheel hub is locked down. And then your belt is spinning the axle, which then spins the rotor relative to the stator. And so you get electricity. If you wanted to use a chain like a bike chain to drive your rotor instead of a belt, there's two main ways of doing that quite easy. One is just to cut off the end of the hub that has the sprocket set with the bearing assembly intact. And then that should be able to fit. If you get like one of the bike wheel with a small enough bearing assembly, it will fit down into the front of the rotor there. So you will want to do it in the order of locking your axle into the rotor, as I described before. And then second, attach the gears onto the front. So I've just drilled three holes here and then drilled out just to a larger radius. So they'll take those bolts, three holes there. And then this part here is just small enough to fit in that part there because it's kind of circular. It centres it. So you just put them there, line it up, put a bolt through, get it in the hole, put a nut on the other side of that, tighten it up, do that three times. And then once you've got those two locked together, then you place that through your stator like so. And then lock off your other side so that that's all locked together as one unit. You'd run your chain from whatever around there as that turns the rotor. You're limited then to only be able to turn that in the direction that it engages the freewheel, if you try to turn it the other way, obviously that happens. The other way is to, if you've got to say, have an intact hub, say I've got the alternator sitting here and then lift the sprocket set on. If you fuse in some way, if you attach the sprocket set to the axle, to the shaft, then as the sprocket set turns, it will also turn the shaft, which will also then turn the rotor. So you can do that either by welding a plate across. If you do that, then you're not going to be able to take the thing to pieces if you wanted to clean out the bearings or something afterwards. Or if you've got a type where the sprocket set teeth face inwards and turn with the sprockets, then you can cut like a little square of steel, drill a hole in it, and then sink that in so that it engages with those teeth and grabs onto them and then lock that down with a nut or something. And then as the chain turns the gears, the gears turn the axle, and then the axle turns the rotor. And so that's it.  Yeah, if you have any questions, just let me know in the comments or contact me directly. And if you build, if you attach one of these to any kind of turbine, anything that you're working on, please do let me know how you got on. It's always good to see results and things being put to use. So enjoy. Thank you.


Those that have stayed progressive and relevant and constantly upgrading their thoughts every day will be the ones that will get the job, the opportunity, the responsibility, get the ideas, have the creativity because they kept clicking download now, if you like, on thousands and that's what it is, thousands of small incremental things every day that you stayed closed-minded to because you thought you knew it all, you'd thought it through, or you think, well I know what to think about that, don't do that, stay open-minded, stay versatile, stay curious, well stay agile in your thinking.


Now that the lottery is behind us, let's mock draft those lottery picks. Victor, Scoot, and Brandon Miller were very easy for me. It's not even a question that Scoot is the second best product in the class. He's going to fit fine there. The Hornet should not pass on him. Mockets get an elite upside playmaker and a man Thompson. The Pistons go Cam Whitmore. Magic could go a lot of routes here. I love Anthony Black's versatility. Pacers sprint to the podium to get Jarrus Walker. The Wizards finally take a point. Garden case and loss. Jazz go for some upside and a star Thompson. Taylor Hendricks to the Mavs is the perfect fit for them. This is where it starts to get tricky. I think Keanu De George is awesome. He could be a future all star. Very Anthony Simon's life. Grady Dick falls to 12 so the Thunder scoop him up. Gigi Jackson, a lot of upside for the Raptors. This is going to be if they trade an OG or Siakam and do want to go full rebuild. And the Pelicans add some needed scoring and versatility in the backcourt and Nick Smith.


default is like autopilot on your life, accepting that you'll never be any good at that, accepting that you shouldn't really aspire to that. Default is this autopilot going along in life, accepting this stuff. And what you have to do with limitations of default is you have to take manual control of your life. You have to take your life off autopilot setting and grab the controls for yourself and start flying your life manually. Start saying I refuse to accept this about me that my family and friends and sometimes family and friends are the worst at putting default limitations on us.