 I think we are probably ready to start. It looks like people have stopped filtering in a bit. And this afternoon, this talk is going to be on auto-wiring containers. My name is Bo Simonson. I'm the technical product manager for Sensio Labs. If you want to find me on Twitter to heckle me virtually, you can find me at Bo Simonson. And you might also know some of the other things that I've worked on that are semi-Drupal related, or at least Drupal community aware. I created GetSculpin, or the Sculpin Static Site Generator, which, at least for a little while, a lot of Drupal people were using, because it was a good way to learn about Twig. And StackPHP was another project that I created. And that's actually part of Drupal Core now. It's one of the things that's used to help bring symphony components into Drupal 8. This talk is going to start out with a little bit of terminology, just so we can all understand what we're talking about here. I'm going to talk a little bit about my personal history with containers and auto-wiring. And then we're going to look at some of the current implementations of containers and where auto-wiring exists and where it doesn't. And then we're going to look at the future. Specifically, we're going to look at the future of symphonies, dependency injection component, when it comes to auto-wiring containers. So this is the first talk I've ever given, where I've bothered to break out solid. How many people have seen talks talking about solid this conference so far? OK, not a lot of solid talks at Drupal Con. OK, sounds good. One of the reasons is that sometimes these acronyms are a little difficult for me. Every once in a while, forget that the D in solid is not dependency injection. The D in solid is actually dependency inversion. So there are slightly different things. The dependency inversion principle talks about decoupling dependencies between high level and low level layers. So it's not exactly dependency injection, but it does sort of have to do with how things talk to each other. Dependency injection is more closely related with an idea called inversion of control. And the traditional way the programs are written, and I imagine at least a good chunk of Drupal applications were written, is that you would just construct your objects as you need them and as you go. So you are taking full control over how your object graph is being created. The idea of inversion of control is taking that information or taking that path in and inverting it so that something else is creating the objects that your application is using. Probably one of the better known implementations of inversion of control is dependency injection. So this is where dependency injection comes from. The idea that something has inverted the control and is now creating the objects, the dependencies that your code needs. So that's what dependency injection is. It's actually an implementation of inversion of control. Another well known implementation of inversion of control is service locator. And this is why service locator and dependency injection sort of get confused by people because they do similar things, but they have subtly different meanings. Service locator, instead of being handed the dependencies that your object needs, it gives you a way to easily go get those objects without still having to know how they were created. So a lot of the dependency injection and inversion control containers are also service locators that let you get the objects that are in the container without having to actually say how those objects are created. So if we look at how these things are related, you see a lot of overloaded names and shared parts of the name. So we have dependency inversion, which is part of solid. So we have the dependency name there, which is also in dependency injection, which is actually an implementation of inversion of control. But it's sort of like dependency inversion, but not the same, even though they both have inversion in the name. And then there's this thing called service locator. To make things even more complicated, a lot of people will use another term that they stick on these to talk about the thing that holds all of the objects. And they usually call that a container. So you'll see something like a dependency injection container. You'll see an inversion of control container. You might see a service container. And sometimes you might just call them a container. And often when I'm talking about containers, people always think that I'm gonna be talking about Docker. Well, you're talking about Docker containers, right? I'm like, no, you need to see this slide because it's completely different. So it's a completely overloaded name, but it's something that it will be very helpful for you if you start realizing that container can mean other things. Another term when you talk about these sorts of containers is this idea of wiring. And wiring is what you use to actually tell the container, or tell whatever piece of code is doing the inversion of control, how these objects relate to each other. So that's generally giving it class names, that's telling it arguments for the constructor. Sometimes those are gonna be, they might be primitives or they might actually be a reference to another object that's defined in the container elsewhere. So this is what one of these files might look like. You would not have to look at it too closely now because we'll talk about it more later. But when we talk about wiring, that's the idea that we're talking about. So a little bit of history, at least my personal history on where these things came from. My first experience with a container was with Spring Framework's IOC container. How many people have used or heard of Spring Framework? Fair number of people? Well, okay, that's about half. It's pretty cool. I first used it in 2007. I switched from PHP to doing Java script, or sorry, Java for about two years. And I was initially confused in the Java ecosystem because Spring talked about these things called beans. So these beans, I thought, were related to this idea of Java beans, which I hadn't really understood at the time, but they called them beans and I didn't really get it. It took me a long time to realize that a bean was just an object and it had nothing to do with Java beans. This was just what the Spring Framework had decided to call the objects that were in its container. I decided to use the explicit wiring, so this was actually telling the objects how they interact with each other. And I chose XML over annotations because I thought annotations were evil. I didn't like them in my code anywhere, and these were actually proper annotations in Java as opposed to the common base annotations that we have in PHP. So I really liked the XML because I felt like I understood what was going on. And what that looked like was an XML file with a container called beans, and then you would define each of the bean objects independently, so you would give it an ID, you would tell it which class that bean represented, and then you would give it some of the information that it needed in order to create it. So you might give it a property, you might give it a constructor argument, anything along those lines that the object needed in order to be created. You could then ask the Spring Container for the message object, and it would make everything for you, and you would get back a message object that you could work on. So I was excited about this idea. I hadn't seen it anywhere else before in programming, so I talked to a friend of mine that was working at Google, and he told me about a project called Google's Juice. Google Juice was a lightweight dependency injection framework for Python. Python also has this sort of annotation type thing, and it based its idea on this inject, an inject, I can't remember what they call them, but it's basically like an annotation. So you would tell, in this case, the real billing service that you want to be able to inject things using Juice, and then you would get an injector for that object, and then you would ask the injector to get an instance of the thing that was configured. And this all seemed kind of interesting to me, but it sort of suffered from a problem that I thought the Spring Frameworks suffered, which was what happens if you need multiple instances of an object just to configure it differently, because that seemed important to me, and it seemed like a really great problem that would make auto-wiring pretty much useless, or this sort of auto-wiring system useless. And his answer was not very satisfactory for me. He basically said that doesn't happen very often when it does, you can get around it, and that's all he said. And that seemed to be all I could ever find online when I looked up these problems was, it's never very often a problem, and then there's always some really obscure way to fix it. And it turns out he was right. You know, after I finally started using auto-wiring a lot more, I realized that this big barrier that I'd put in place was an issue that wasn't really gonna happen very often. There were a few edge cases where I would end up having to do this a number of times, but those were very few and far between. So it wasn't really as big of an issue as I thought it was. So after I got done working on Java for two years, I wanted to bring this back to PHP. So I wanted to try and use some of the ideas that I used, or that I'd learned in the other language in PHP. The problem was that I sort of was my own little isolated island. I didn't really have a lot of people that I talked to. I wasn't in the community in any way. So I ended up writing a lot of my own code and reinventing the wheel. So I created a little container I called Substrate. And this was gonna be an inversion of control dependency injection container for PHP. And I didn't really learn the lesson that beans were confusing, and I decided to call my little object Stones because that had something to do with Substrate. It was really ridiculous. I look back and I laugh at it now. I stuck again with explicit wiring because PHP at the time didn't really have annotations. And if they did, it was very like one-off people trying to do some weird hacks with thought blocks. So it just made sense to stick with explicit wiring. So the way that it worked was a lot like spring worked. You would have a context object which was essentially a container. You would add something, you would give it a name, and then you would give it the metadata to help wire things up. So in this case, we look at a class name of a properties configuration, and then we can see that it has constructor args. And you can pass all the information in that you need to do. So this was really great. I like this a lot. It really fit my needs pretty well. Then I started adding this idea of auto-wiring. I'd seen this in the spring framework, but I didn't really understand it. Didn't understand why it needed to be there. And I implemented it a little differently, but it turned out to be pretty much the same. The idea was that as you were constructing a new object, you could go over all of the parameters for the constructor. If that parameter had actually been defined in the container already, it would just use the reference to that object, which means that you were able to automatically put in anything that was already defined as an instance within that container. Otherwise, it would use whatever to actually come off on the configuration. So what this meant was that if I had, say, a file logger, and I had a log factory that needed a file logger, my configuration now would need to know about the logger. So I'd have to define the logger. I would give it its constructor args, and then I would add the log factory, but I wouldn't have to specify the file logger anymore because it was able to actually find that within the system already. But as is always the case, it's better not to always reinvent the wheel. I started shopping around for a new framework, ended up on symphony. I started to feel really familiar because it started out more or less, as I understand, a port of some of the spring framework ideas. So it felt really familiar since my own internal container was based on spring as well. I was particularly excited about the dependency injection component because it was a standalone thing that you could use in symphony or you could use it in your own applications. So it was pretty exciting for me. They had a bunch of other stuff that was great as well, but this was the one that I was the most excited about. It was very flexible, unlike some of the other PHP containers that were starting to grow around that time. It seemed to be able to do a lot. It had a lot of different ways to load the configuration. You could do a PHP, you could do XML, you could do YAML, all of these things that were just built in to it that just made it really, really pleasing to work with. It also had these things called compiler passes, which were extremely confusing for me to get at first, but they were very powerful. And the most interesting part about the compiler passes is that the symphony container can be compiled. This means that you don't have to interpret the binding, the wiring code every single time. You're able to create this big, huge file that has all of the services already defined so that you don't have to go through and execute that code every time to find the dependencies. So now that we've looked at kind of the history of where we were, we're gonna take a look at a couple of implementations. The first one we're gonna look at is a file called k.php. This is in almost all of my projects along with kk.php, k3.php. Basically any random text that just has a bunch of procedurally generated, or procedural code to try and test out the project. So it's just basically a file that has inline php in it. We're gonna start with a really specific class called important service, and it's gonna use one of the logger factories. And it's going to do an important task, which at this point is only going to log that it did that important task. So this is kind of where we're gonna start. So we're gonna add this class inline into k.php, and then we're going to create those objects by hand as they relate to each other. So we create the new file logger, we create the file logger factory that needs a file logger, and then we create the important service that needs the logger factory, and then we can ask that important service to do something. So this is the opposite of inversion of control. So if you're wondering what inversion of control is, really, this is the opposite of it. So anything else where other people or other parts of the code are instantiating your objects for you, you're doing inversion of control. If we wanted to do something like this in symphony, like the current stable versions of symphony, we could use a YAML file to do the same sort of thing. We can specify that the service is key, we're gonna name it file logger, give it the class, give it the arguments. We're gonna do the same thing for the logger factory and the important service. As you can see, these little at signs mean it's referencing the services by name. So that's how it actually references existing objects within the container. And then you can just get the important service by name from the container, and then you can do with the important task. So this is how most of the containers are going to work. It's gonna be some sort of wiring, some way to get an object out, and then you can use the object as you would normally. The XML loader version of symphony's container has a little more verbose. So you end up typing a little bit more, but there's also a lot more validation that can happen. So it's the same exact end result, it's just different inputs. And this is one of the reasons that the symphony container was really nice when I first started looking at it, because it let you do either. There's another container used behind SILIX. How many SILIX users are there? Okay, a handful of SILIX users. SILIX is based around a container called Pimple. And the way that Pimple works is it uses an object that sort of acts like a typical array, and you define the keys by name that then call a factory. So the factory's job is to return the object for that. So we have like FileLogger here, and we're gonna say return new FileLogger. LoggerFactory is gonna return new LoggerFactory. It gets the container passed in, so you can ask the container for FileLogger. So this is the way that this kind of container configuration would work. There's another container called IlluminateContainer, which is actually Leraville's container. And I believe that it originally started out, Leraville originally started out using something like Pimple, or used Pimple itself, but it gradually changed so that it started to use functions or method names rather than using it as just an array. But otherwise it looks almost identical to the Pimple implementation. It's just that it's using method names instead of doing direct accessors. One of the things that the Leraville community started to do that I thought was great was that they would start to, instead of using the made up names here, they would actually use the class name of the object that was in question, which I thought was just brilliant. This was so nice because one of the things that I really didn't like about the symphony stuff was that I always had to come up with an ID. And generally it was basically copying the fully qualified class name and replacing the backslashes with periods, which you'll probably see that. Sorry, you'll probably see that quite a bit. That or else you would end up with a completely shortened version of the name. And it was just kind of annoying for me to always have to go in and do that. I always felt like that was something that I didn't like to do. So I thought this was kind of a great thing. And the thing was that I hadn't realized until I had been using it for a little while that if I had done something like this with substrate, it would have been pretty awesome because what I could have done is look to see whether or not the stone instance existed for that class name. And if it didn't, I could actually ask the container to just make that parameter name. So it would actually go and make the class name. So I could specify class names now and even if that didn't exist within the container config, it would know that the class name existed. It could still do the reflection on the class name and build everything up from there. So this would have actually been really nice had I realized that this was even a possibility. So what this looks like in the terms of like an auto wiring container, like what Lareville has, if we look at important service, the container is being asked to make the logger factory. The container knows that it needs a logger factory and it can create it by logger factory. Do we even need to specify that we need to do this? Like do we even need to specify important service class at all because it's gonna go over all of the arguments, find out that it needs a logger factory and then it can go get the logger factory. And the answer is no. We don't actually have to specify that anymore. And the same thing here. If the logger factory needs a file logger, the container knows how to make a file logger. It doesn't actually need to define that either. So the container configuration keeps getting smaller because the container is smart enough to create the objects for the classes that are in question. Where it gets a little more difficult is if we start looking at something like this where we need to be able to find a way to inject a string primitive in this case, we need to do something a little different. And the way that Lareville handles that is it has something called binding primitives where you can say when the file logger needs file name, give it this value. So now the container configuration only consists of this one setting to bind these values. These sorts of auto-wiring ideas are really great when you start looking at change. If we wanna change important service now to do something a little more, like do something with the connection. Maybe it's actually gonna do something now, it's gonna execute something on a connection. What we do is we would add the connection as an additional constructor arc, we would type hinted, and then we would ask the connection to execute something within the do something, do important task method. If we go back to the procedural implementation, this isn't too much worse, you have to add the connection part, and then you have to add the connection to the important service constructor. If we look at the services YAML file from symphony, you have to add an additional connection class now, and you have to update the important service to reference that in the arguments. Same thing for the XML version, you still have to add these additional bits so that you're now referring to the connection object with the connection ID. Similarly in pimple, if you wanna add another object, you just have to add an additional connection here, and then you would have to update the important services to do the connection. If you look at an auto-wiring container, what you end up having is nothing. So because the important service knows that it needs a connection, and because the container can build the connection on its own, you don't have to change anything. So you can start adding dependencies and adding whole classes without ever having to modify the configuration for the container that you're using. This was something that I started to think about like, middle of last year, was that there were a lot of things when I was using the symphony container that sort of drove or impacted my design, because I no longer wanted to add a new class or do some refactoring, because any time I changed the classes or the hierarchy, I'd have to go in and change the configuration as well. And converting the k.php file that I would always have with all of this procedural code, I would dread when I actually decided to try and create the configuration for that, because I would have to wire up the entire thing, and it wasn't just working. So I found that this really started to impact my design and my development, and it was just a subtle thing in the background that I hadn't really realized until I started really using an auto-wiring container and realizing that this was having an impact on me. So the pros of an auto-wiring container are that it has an amazing developer experience. This is something that Ryan Weaver in the back is all about. I think that's his buzzword that he's excited about. It's an amazing developer experience, because you're able to do things quickly. You're able to not have to worry about configuration as much. So it's great for heavy refactoring sessions. If you want to take a dependency out of one class and inject it later, or inject it into the constructor instead of having it inline in your class, you can just do that, and chances are you're not gonna have to actually change any of your configuration. For me, it leads to more code writing. I can actually focus on writing code and not have to worry about configuration. I just don't have to worry about it anymore if I'm using an auto-wiring container. And it works like magic. It just works like it's supposed to, which is awesome. If you're into magic, it's really great, but I know some people aren't into magic. The cons for doing auto-wiring containers is that it's not really good for performance, especially if you're looking at Laravel's implementation, where it's all callable-based. It does a lot of stuff with reflection. It does a lot of magic behind the scenes. So it's doing that every request. So this actually becomes, at a certain point, at a certain scale, it starts to impact performance quite a bit. And if a container like Symphony wanted to do this, it would start to become difficult to optimize this, because all of a sudden you're looking for classes that aren't defined yet. At least with the current implementation of Symphony Stable, you're looking at a class that has to be in the service container in order for it to be able to be wired so that it could be dumped, so that it could be high performance. That's just the way that it worked. So at least initially, this idea of auto-wiring for anything but something like a Pimple or Laravel-type container was gonna be really difficult. And of course a con is magic. So if you don't like magic, then you're really not gonna like auto-wiring. So in the future, I sort of see this best of both worlds sort of thing happening. What I'd really love to see is Symphony's container, like all the power of the compiled container, all of the compiler passes, and all these really great things that Symphony's container has, but also have the developer experience that you get from auto-wiring containers. So I was really excited when Symphony 2.8 was released because I saw this really cool service auto-wiring thing that came out. And then I looked into the details and saw that what it really did was if you had a services configuration like this where you're referencing service one, you could auto-wire service two and then you wouldn't have to define service one anymore. But for me, like this really didn't seem very good. I looked at it and I think I gave Ryan a hard time at Symphony Live one year, cause I'm like, this is great that we have auto-wiring, but you're still having to do all this stuff. It just didn't really make a lot of sense. So I was kind of unhappy about it, but I wasn't a very good community member because mainly I just complained to Ryan about it, but I didn't do anything. Fortunately, there are other people in the community who actually started to look at this and try to make things better. So one of the first auto-wiring bundles that I looked at in recent time was an auto-wiring bundle that had this idea of looking in certain directories and making certain types of classes where you could make them auto-wiring by default. So now at least we had one last level where we had to say auto-wire true because to me, if you have a class, you have to define it anyway and say auto-wiring true, it's not gonna be user-friendly. The really exciting package that I ended up looking at was the Action Bundle. And the Action Bundle, its job was that it was gonna scan directories and what it did was it dynamically created objects that could then be dumped into the container, the dumped container that had services generated with the class name as the ID. So whatever class name that it found in the directories was gonna be the ID. And then it was actually gonna enable auto-wiring for them. So what this meant was that you could now create a controller like this one, this homepage, that has a router interface and a twig environment that needed to be injected into it. And it would just do this. The container would be able to create this object called, or create both the class name of homepage so you could just ask it for it. Without any configuration, the container didn't have to do anything anymore. So this was really, really exciting to me. The other exciting thing was it turned out this wasn't limited to actions. As he worked on it more, he realized that what he could do was scan any directory and create the same sort of services. So it was something that wasn't just tied to controllers anymore, which was pretty awesome. So what we get with this is a very performance friendly container. We get the optimization of being able to dump the container and we get the developer experience of not having to, at least for controllers, or very specialized types of objects, not have to do any sort of configuration for them, which was really great. What's going to be really cool is that almost all of this now is baked into symphony. So symphony 3.3 has a bunch of really cool features that cover almost all of these cases and make auto wiring and something else called auto configuring a part of the core symphony experience. So I'm super excited about these and we're gonna talk about a couple of them. The first one is that optional classes can now be, optional, the class name is now optional for the services to find in the symphony container. And what that means now is that if there is no class name defined for a service, it's going to use the service ID as the class name. So we get to the point where we can actually have our class name as the key, so we no longer have to generate IDs or think of IDs or do any sort of things like that, we can just specify the class name as the service name and then it just does the rest. Couple this with auto wiring means that this becomes very, very tight now, which is very, very cool. However, we still end up with this auto wire true business, which is fixed in PR 21071 where we can actually now configure defaults for some of these values. So what that means is that rather than having to find class names with public and auto wire true across all of your classes, you can now define defaults with public false and auto wire true, which means that any of the classes defined within this configuration file now are automatically going to be auto wired. So this is starting to make things very interesting. Now you might have had 15 classes defined before where you had to basically duplicate this information if you wanted them auto wired, you no longer have to, which is really, really great. But we still have to actually define the classes which is fixed in this PR called PSR4 based discovery and registration. So this is sort of some of the functionality that was in the action bundle where we actually can specify a PSR4 based name. How many people know about PSR4? Okay, it's fair number of people. It's another auto loading standard if you aren't aware of it or you can specify where things are. So this is PSR4 based. So here we see app controller. So you don't have to have app also in the function or in the directory structure like you would with PSR0. So here what we're saying is that anything within source controller or source command should be scanned. So it's gonna scan those directories now to find all of the classes that are within those directories. And these, any values that you put below then apply to any of the objects that are gonna be created as services automatically. So if you have a controller called home, you're gonna have a service called home and you're gonna have it auto-wired true by default. So this starts to get really cool because now we're not even having to define the actual, define the actual class names anymore. Basically any controller you create or any command you create for your console application is automatically going to be scanned and picked up for you. On top of this, there's another interesting thing that was added to sort of alleviate another issue that would come up with the configuration as far as having to do a lot of things over and over again. And that's especially important with tags. So what this is saying is that every class within source action command events subscriber or twig is gonna automatically be scanned. Any of those classes that are automatically scanned that are an instance of a command were automatically going to tag it with console command. So that was another thing that you would use to have to do with symphonies container is that you would tag things as a command. You could tag things as a twig extension or a kernel events subscriber. You no longer have to do that anymore because we can actually do these things in bulk. So we're gonna scan all of them and then add the tags as we need to depending on what kind of object it is. Then the team took it a little bit further and decided that why do we even have to do that? Like why do we have to tell people that? We know that we have event subscriber interface and that everything that's an event subscriber interface implementation should have this tag. So why do we actually need to do that? And it turned out we didn't. We could leverage this instance of concept. So now there's a new key called auto configure true. So here we have app bundle event listener check requirement subscriber that is automatically going to be configured as a kernel event subscriber because that's all handled by core now. So this means that all we have to do is specify the class name. Now if we couple that with the PSR4 resource and registry we wouldn't even need to have to do this. So the file gets very, very small and the configuration that's required to put these things into place suddenly become a lot easier. There's also an idea for named arguments in 3.3 and what that means is that if you have an object that is going to be auto-wired but you have additional things that can't be auto-wired, this is sort of like the binding primitive stuff that we looked at earlier, the way that this is handled now is that you define auto-wire true for all of the services and then you just say that for this particular object the API key needs to be this value. Auto-wiring picks up everything else. So this new syntax is all you would need to do to completely auto-wire this service because it's able to get everything else. We're just telling it where it can get things that it can't automatically determine on its own. And if you wanna use the longer syntax that is currently available, you could do this as well. So you would say arguments, you would specify API key needs this value and since we have auto-wire true, it's gonna still automatically inject everything else for you correctly. This whole idea of auto-wiring enabled another idea that we had and this is a way to inject objects into controllers and this is gonna be in Symphony 33 as well. So if we look at the original home controller that we had earlier, it needed a router and it needed a twig. What this can do now is we have a home class, doesn't extend anything at all and we have my action, which we're routing to my action. And we can ask for the request like we normally would but we can also say that we need a router and we need a twig for this action. And what that is going to do is look and say we don't know where this comes from otherwise. Like if it's not already coming in from some other reason off the request, it'll actually go to the container and say, give me whatever implementation of router is currently registered for the router class. So it'll go and look for these things now for you. So it means that the old best practice for Symphony was that for controllers you would generally look at the service locator itself. You would inject the container and ask for the services back out of it. And that was just because it was the best way to do it, the easiest way to do it at the time. And part of that problem was because if you had one file, one controller with say a dozen actions, they might all need slightly different dependencies. So some of them might need the twig router, some of them might need some doctrine repository to get information out of the database. Some might need an API call. So like you might need an API client of some sort injected. So rather than trying to inject all of those in constructor injection, you would just inject the container and ask for things as you needed them. So they were kind of lazily loaded. With this, you're able to now say that this particular action needs these things. So if all of your functions need to access say a post repository, you could inject that in the constructor. But if you need something special, just for a specific action, you no longer have to inject that into the constructor where you're not gonna use it every time. You no longer have to inject the container and get that special object out when you need it. You just add it onto the dependency list on the function itself and the auto wiring container can go in and get that information back out. And all of this is really gonna be coming together really nicely with Symphony Flex. If you wanna learn more about Symphony 4, Symphony Flex and some of the cool things that Fabian is putting together for the next few releases of Symphony, you can check out his blog. It goes into a lot of this in more detail. But the coolest thing about Symphony Flex is that right now as things stand, this is the default application configuration for the container. It specifies auto-wiring true. It specifies auto-configure true. So we're gonna automatically auto-wire everything and we're automatically going to be able to tag objects that implement certain interfaces so we can automatically tag twig extensions, console commands, anything like that. We're gonna do the PSR4 registry for commands, form, event subscriber, twig and voter. So all of these common things, as long as you create classes within those directories that are appropriate to put in those directories, they're automatically gonna be auto-wired. So in theory, you won't have to do anything at all to add a twig extension. You just add the twig extension and it just works. You might have to re-load your cache if you don't have the development mode on, but for the most part, you won't have to do anything at all. You won't have to define any additional services. For the app controllers, we have those set as public true because they need to be public, but we also are going to tag them all with the service arguments by default so that any controller you create can start leveraging this functionality where you can start requesting dependencies at an action level within a controller. So this is very exciting to me because this means that out of the box, symphony flex applications are gonna have full auto-wiring, have all sorts of cool builds and whistles that just work and it's gonna make a whole lot of developers' lives a lot easier because you're not gonna have to worry about the configuration. So I really do see this as the best of both worlds. We have a really great auto-wiring container now within symphony and we have the full features, like we have all the powerful features like compiler passes and being able to dump a compiled container. We have that all now within the symphony container. So a lot of people, like I've actually talked to some people after the talk, if this has convinced them to use auto-wiring or not and usually no, if you are already staunchly against auto-wiring before you probably are still so. But the thing that I like the most about it and the thing that I want people to consider is that what this turns into is not just everything is auto-wired, it turns into only worrying about the exceptions. So if you're worried that, oh, if I start auto-wiring, I'm gonna run into a case and I'm gonna be pigeonholed into this thing and I'm not gonna be able to fix it, don't worry about it. If it doesn't work, wire it by hand. There's no reason you can't continue to manually wire some of your dependencies. It's not an all or nothing sort of thing. The auto-wiring is there to handle the 95, 96% case of everything working, but the manual wiring is still there if you wanna try and do something that is outside of what auto-wiring allows for. So I would just say give it a try, especially once the symphony flex stuff gets published, it'll be really easy to just give it a try, look at the app container, start creating controllers and just seeing that you can just create controllers. Create controllers and everything works, so yeah. So I would say give it a try. How many people want to give this a try now? Awesome. All right, that's better than in the past, so that's pretty cool. So last thing I wanna talk about is I'm sure you've seen this slide a bunch of times. There's supposed to be some sprints on Friday. Ryan Weaver and I, I think we're both going to be here for that, I know I am. So if you wanna talk about symphony 3.3, you wanna talk about the container stuff, you wanna talk about flex, if you wanna talk about Blackfire, our performance tool that we have, feel free to try to ping me or Ryan on Twitter and line that up, otherwise if you wanna try and get contributions into Drupal, this is a great chance to actually do that. So if you're kind of on the fence, hopefully I've pushed you over the fence on that one. If you can give me some feedback, either on Twitter, I think you can actually give talk feedback on the Drupal website itself, that works as well. Otherwise I have time to answer some questions, I think. Do I have time? I don't know what the schedule says, but if you have questions, raise your hand and go to the thing. Yeah, if you can go to the mic, that would be helpful. Yeah, no problem. Do you know if this is planned for like D9? You know, that's something that, I don't know if Fabian knows or if anybody who's... So the question, Ryan's in the back, he answered it, I'll answer it for people who need the mic or the recording. It sounds like Drupal 8.3, was it? Or 8.4. Drupal 8.4 is going to be released. Okay, so the plan is that Drupal 8.4 is going to go with whatever the most recent version of Symphony 3 will be, and at that point, it's either going to be Symphony 3.3 or 3.4. So all of the stuff that we've talked about here should be included in Drupal 8.4. Thank you for the question. Yeah, I actually attended Ryan's tutorial with Drupal and Symphony on Monday. I was one of the helpers, and there were a lot of things in there that were related to Drupal, my bad, related to Drupal and to the Symphony that I just know this stuff is going to make a huge help, because anything that you add, if you want to add certain types of event listeners and things like that, it'll just automatically work. Like if you get the instant stuff working, yeah, you won't have to define those things anymore. You'll just generate them on the command line, and then they will just work. And so I think it should be pretty cool. Any other questions? So I just want to be reassured on something here. Okay, so the auto-wiring is dependent on having the fully qualified class name as the service ID, right? So, I mean, it just seems like if you're doing that, then you're kind of limiting yourself with the ability to substitute a compatible service. So if I have some user management service, and then I want to swap it out for something different, and all my methods are compatible and whatnot, then I can, so just tell me this isn't a big deal in real life? Yeah, so this is the question that I asked, and I never got a satisfying answer on, that whether it be swapping out implementations for an interface, or if you have the same object that needs to be, or the same class, you need six instances of it for whatever reason are differently configured. I wrote a read model for an event sourcing system where I had a common key value pair sort of thing, where I wanted the instances to always use the same PDO instance to do the actual SQL query, but I wanted the table name to be different for each instance. So that's the type of thing that I think it's very important that we're able to support with Symphony 33. There is an open PR suggesting some solutions for that, but that one hasn't been merged yet, and that one is kind of contentious right now, as to whether or not it will be. But I did actually have some additional slides showing how this sort of thing works, at least with the layer of implementation. If we look at, here we have logger factory wants a file logger. This goes against the dependency inversion principle because a logger factory shouldn't know about a file logger. What it should know is about a logger, and then the file logger should implement logger. So this is actually properly looking at like the dependency inversion principle. So the way that Larival would handle this is that you would specify that the logger class is bound to the file logger. So when the logger factory is instantiated now, it's gonna want a logger, and the container's answer is like, oh, the logger is a file logger. So the way that we would do that in Symphony World is probably either using the bind parameters or using the bind PR that we're looking at, or you could actually set up an alias. So you can already do something like this where you can say, in the YAML configuration, you would just say that logger class colon, I think it's at, file logger class. So we would already be able to do something like that that does part of it. So this is how you would swap out an interface, but this is globally. So this would be swapping it out globally. Anytime you want a logger, you would get the file logger. So then the next problem, of course, is what if you want multiple instances with different configs? So the way that that works is with, at least with the Lairville system, would be contextual binding, where you would say, you have a no-logger, you want an unimportant service that needs to not be logged. So the way that this would work is that you would say that when the unimportant service wants a logger factory that would do a function then to create a logger factory with the no-logger so that when you make the unimportant service class, it's going to get the logger factory that has the no-logger in it. But if you do the important class, you would get the other one. So this still is all about exceptions. So this is the exception that logger class can't be instantiated. So the configuration for this is gonna be file logger. So that's an exception. If you want, so any class now that needs a logger is gonna get file logger, except where we've put up a rule to do an exception here. So this is the one that I'm not exactly sure how the symphony container is gonna support this yet. This is one of the, like I said, it's a contentious PR because we don't really know the best way to implement this because people need to use it first before we can see when these cases happen. I know that I ran into valid use cases for this with the READ model example, but there's probably other ways we could do this as well. I know that I've worked around this sort of thing in the past by creating wrapper classes that are basically just decorators with a specific class name then that I can use to type in that class name in certain cases. And then I would get everything that I wanted, but let's kind of work around your container instead of actually trying to get the container to do the work for you. So this is how you would solve these sorts of things. I don't have any doubts that we will finish some sort of solution or we'll have some sort of solution for this for symphony 3.3. And if it's not in 3.3, I'm sure we'll have something by 3.4 that will solve these issues. So I hope that answers the question. Unfortunately, I didn't have a symphony example for that, but it is a case that I know that I had personally, but again, I had to use this for a very long time before I ran into that edge case, probably like a year and a half of doing auto loading where I didn't, or auto wiring where I just didn't care until I ran into this particular use case. So it is something that at least in my experiences happens very rarely, and there is a way around it. It looks kind of ugly, but at least in this case there's an example of a workaround. Yeah, thank you for the question. Any other questions? Cool, all right. I guess I'll let you all all go. Thank you. So, let's go ahead and start with this one now. Well, it says, but that's what we're going to do. So, that's the good thing about this one. So, that's the good thing about this one. I've never read a question. It only has to get out of the way, because all you have to do now is read it out. That stuff, you know, has to get out of the way. So, the problem with this one is that we're going to have no way to get it out of the way. So, we're going to have no way to get it out of the way. And, then this is going to end up as this last case that you talked about as a convention. So, it could change but it's going to be a thing. So, it's going to be a thing. And, then this is going to end up as a convention. So, it's going to be a thing. So, we're going to just, so got our, we're going to have a lot of questions left. And, then that's going to end up as a thing. So, I guess the hard part of this is we're going to need to do for example, we're going to need to Skype Yeah