 My name is Richard Miller and you can find me on Twitter and it is Mr underscore r wool Miller, which is a slightly awkward things I didn't realise how annoying it would want on it. I worked with 18-0 labs in the UK I am based in Shefffield Mae'r ddaf yn oed i ni'n gweithio'r newid yn ymgyrchol rhywuniaeth o gwybod drwy'r ddechrau. Rydw i'n rhan o'n meddwl y syniad bwrdd. Rydw i wneud fy modd o'r rhan o'r cyflawn. Mae ydych chi'n gweld ar ôl i gael. Mae'r rhan o'n meddwl i gael ac yn ystod yn ei gweithio'r rhan o'r cyflawn. Dwi'n dweud ond y cwrdd yn cael ei roi gydag. Yn gweithio'r cyfradd yma, mae'r cwrdd yn cael ei grannu gweld yn meddwl angen. was it's quite difficult to, we're sort of writing code for one customer and I'm wanting to reuse a slight different version of it somewhere else for another customer and sort of running into all kinds of problems about how to, you know, end up maintaining multiple versions of it or having all sorts of kind of complicated code to work out which version of code we should be using for that customer. And it's sort of finding out about dependency injection and how that worked and it really helped me to start to sort out that code base and at the time it wasn't hugely popular as a technique that people used in the sort of PHP world but sort of read about it in blogs and things from Java where it was used a lot more extensively. And then when we sort of came to our senses and realised that maybe we should be using one of these other great frameworks that are out there instead of persevering with our own not so great one. It was one of the things that really sort of, I liked about symphony, so it was the symphony two which we sort of started using, well started investigating and looking at when it was in a beta version. So what is dependency injection? So it's a technique for an object oriented programming where we separate what objects we're actually going to use from how we use them and make that separation. So this is it pretty much. So in this example we've got a stock levels class. It needs to use, it has dependency on a notifier object but it's going to make use of. So instead of creating it inside the class we inject it in through the constructor and then make use of it that way. So when we create a stock, instantiate stock levels object it needs a notifier and constructor is going to force us to pass one in and we're separating that construction from the use of the notifier. And that's it really. So if you want to, so and essentially that is all there is to the basic concept of dependency injection. I'm going to talk about sort of like why we do this and advantages but also where some of the complications arise from and why you've perhaps heard of sort of service containers and dependency injection containers and all these. There's lots of blog plays out about how you shouldn't do it. So why should we do it? I mentioned a little bit briefly but if we're going to a bit more detail. So for this I'm going to use the example of, we've got a requirement that after we update the stock level of a product we also need to email customers who has to be notified about it. Presumably I guess notified that something came back into stock, not just every change in stock level. Okay, so at first thing we might create a lot of code so we're going to update the stock level and then do all this stuff and then I appreciate that's quite small. So if we split because there's a lot of sort of code going on, that's what we split what's happening. And so say this is all happening after we've already kind of done the actual stock level updating persisted that somewhere then we're like okay we better notify those customers that want to be notified. So we're going to do it by email so we set up our mailer object so it's sort of a very tedious sort of configuration code. We're using SMTP, here's the certainly address of the mail server that you thought to use, the username and the password. But it's not my usual password. I don't have a usual password anyway but. So we also need to do the same so our customers we're getting from the database, this list of customers. We're using doctrine for that in this case so we need to configure a set up doctrine so tell it in this case we're just using SQLite. Probably don't want to use that for your production database but for the sake of conciseness in the examples. So we create an entity manager in that and it gives us a repository and now we can finally actually do something with this stuff. So we've got use the repository, ask it for the customers that were registered for stock notifications for that product ID. Then that gives us back a sort of group, a collection of customers. We can loop through that collection of customers using for each in this case. For each one we're going to create a message telling them about this product's come back in stock. Then finally we're going to use that mailer object that we created in the first slide there to send the message. So the code we've created, well I created in this case is quite inflexible so there's a lot of hard coded values in there. All the values for like username, password, where to find the server, the fact that we're using SwiftMailer, the fact that we're using doctrine. It's also kind of reasonably complex to follow if you open a file and find that because you've kind of got to look at, read through the details of what's happening. You can see there's a lot of stuff around the mailer, a lot of stuff around doctrine and finally we kind of get down to what we want to do. So what we could do to improve this is rather than just, I split it across slides but we could have actually split that into separate objects first. But I'll do that now so if we split that up. So if we take our stock levels class again there's some other stuff happening before we get to this point. But instead of showing all that instantiation of SwiftMailer and doctrine we'll hide those inside, encapsulate it inside some objects. We've got an e-mailer object now and a customer's object and then we can see that we're going to find all those customers and then notify them. So we've cut out some of that sort of things to read and abstract it away from it. So we'd end up with an e-mailer class maybe like this that hides that SwiftMailer instantiation and a customer's object which hides the doctrine stuff and delegates to the doctrine repository. So it's there, stock level class looks like this and it's a bit easier to read. We might find that both actually about abstraction level might be even more detailed when we still really need to know. So what all we really need to know if we're looking at the critical dates for stock levels is that at that point we want to notify people that the stock levels have been updated. So we can simplify it right down to saying we have a notifier object that we're creating and we're going to notify people about the product and then in that we shift that code that does the actual looping through the customers and sending the e-mails. So we kind of move that code from being sort of complex into something that's fairly simple especially at the level of looking at the stock levels. We now have two lines where we had sort of 30 or 40 before. So we're kind of simplifying each level of abstraction. We can see what's happening. It's only if we care exactly how it's happening that we then have to dig down and look at the source code for that class. So in terms of following the pathway of the code, we simplify that quite a lot. It's still not doubt at all though with any of the flexibility issues. So it's still all very hard coded. We're using hard coded values a lot for the details like where to find Swiftmail, the mail server. So like this is, well to be honest, this code is going to be pretty difficult to work with. So even aside from trying to reuse it in another project, it's like if we want to have a developer environment, a staging environment, a UAT environment and a production environment, hopefully they all point to different mail servers and things like this. So the first thing we could do I guess is we could have some kind of config object with we use static access to to get some parameter values. And that's going to maybe read in a different config file depending on which environment we're in or which project it is. So we can kind of make it a little bit more flexible here. Well just usable at all because we're now able to set those values differently. Okay, so we now have a different project maybe. They're going to not use email. We're going to use SMS messages to inform those customers that things come back into stock. So what can we do to accommodate this in the code? We could use our config again. So we're asking our config object to tell us what the stock notification method is. And then we're going to, depending on the case of that and the switch don't here, we're going to call a different method. So if it's email, we'll notify by email. It's SMS, we're going to notify by SMS. And then we sort of have these methods inside the in stock notifier. So you see we kind of made it a bit more extensible if we wanted to add another one now we'd have to come in here, add another method and actually add another case statement as well. So again, we're going to have to constantly kind of come back in and edit this class. So maybe we could push that choice further up for class a bit. Well, further up the object, graph a bit and say instead of doing it in the notifier, we can maybe do that in the stock level. So in here we say, okay, so if it's email, then we're going to use an email in stock notifier. And if it's SMS, we'll use a new SMS in stock notifier. So now we might have to create a new object to do that, but the only change we need to actually make to our existing code now is to kind of come in here and create a new case statement for that. Okay, so we've made the code more flexible now, we can respond to different config values and we can sort of have different paths through it depending on how we configure it, in this case if we want to use email or SMS. But we have started to grow the complexity back into it. So we've already got those sort of, we've got to talk to an extra config object, we've also got to kind of switch through the different values in that case and we have to keep adding new cases to the switch statement if we want to support different methods of doing this. So if you're doing this throughout a code base, you can see kind of grow quite a bit of complexity and now it makes the facts of it being a bit more difficult to read. There's more things going on than just making use of that object. So what we can do then is use that sort of constructive injection I spoke about right at the start and say when I create my stock level object I'm just going to give it a fully formed already constructed notify object. I'm going to set it to a private variable in this case and then when we get to the point of updating stock levels all we need to do is say notify people about this product update. So if we want to use emails, we instantiate it like this with the email and stock notifier and if we want to use it with SMS then we can instantiate it like this and just use it with an SMS notifier. In this example it doesn't cope with the fact that maybe sometimes you might want to have email some customers and SMS some others but let's just assume it's one or the other for the sake of this. Okay, so by using that sort of dependency injection we're kind of saying I don't want my object to instantiate to say dependencies and have to worry about what those dependencies are I'm going to create them somewhere else, pass them in, ready formed and the class can just say, just use the one that's there it doesn't care which one it is it just knows what it's going to do with them and one of the other advantages is that we're making explicit how many things are depending on so if you end up kind of saying I need this and this and this and you've got this massive constructor that's growing and growing and it highlights the fact that maybe that class is doing too much work itself and maybe there's something else you could do to kind of simplify it and pass them with that work elsewhere. So there was a problem with that version now so if we look back at this so this is a simplified version we're passing the notifier into the constructor and then we're calling the notifier method fortunately we could do this still when we're creating it and say I'm going to want a new stock levels object and I'm just going to pass you some other object it's not a notifier and then I'm going to call update stock level on it and we're going to see this unfortunately so it's a fatal error, we're getting a call to an undefined method because it's not a notifier object doesn't have a notifier method to call so we better make sure that when we construct our stock levels objects it is an email in stock notifier that we get so we can use instance of it one way to say if there's an instance of an email stock notifier it is great, carry on if it's not we're going to throw an exception at this point fortunately PHP saves us writing someone a boilerplate code and we can use type hints on the constructor to do that so this time we're insisting on an email in stock notifier if I try and run this again then I'll get a different error message this time so now I'm saying it's a catchable fatal error although I'm not sure anyone over does catch them but argument one passed to it must be an instance of email in stock notifier instead an instance of not a notifier was given so it doesn't necessarily help us if we're actually running this code in production we've still made a mistake but it means that when you're doing something in development you get a much clearer error message much more explicit about what the problem was it's not just that something didn't have a method you tried to give the wrong type of thing to something and it kind of documents that code as well so if someone's reading it they can say it needs an email in stock notifier not just it needs a notifier whatever on it we have no idea what that is fortunately if we do that with the concrete implementation of the email in stock notifier and then say actually I want to use my SMS in stock notifier we're going to get the same problem because it's not an email in stock notifier so we've kind of ruined that flexibility for the sake of a bit of safety okay so we can solve this by using an interface and typing on that so our interface just says I'm something that, well I'm a notifier and I have a notifier method we can update the definitions of our email in stock notifier our SMS in stock notifier and any future notifiers that we have to say that they implement the in stock notifier we'll get a fatal error then if we don't actually implement the notifier method when we try and create one of those and then we can update our stock level class to type in on the interface and not on the concrete implementation so now we don't really know what my notifier is we don't really stock level class doesn't care what it is that when you pass me that object I know you've got this interface you have this method I can call it happily it may just do nothing it might call out some third party service that helps us like send this stuff out by traditional mail it may be a whole collection of them that sends it out in all sorts of different ways that you'll wrap together all I care about is it has that method I'm going to be able to call it and I'm not going to run into any problems when I do try and call it so what we're saying is that it's great pull apart these classes this way and then by depending on abstractions interfaces for instance we can avoid tight coupling between the classes and actually get that kind of flexibility to wipe them up in different ways and get more use out of each individual class okay so if any mention we've shown constructor injection where we're passing those dependent objects in through the constructor and there are other types of ways of injecting those dependencies and I'm going to briefly talk about those personally I always try and use constructor injection I don't particularly like these other ways of doing it so and the great thing with constructor injection essentially is that it happens at the time you construct an object in that state and you know that it's ready to be used and that no one else is going to change it under you so one of those is property injection which you may see which is essentially just simplifying it down to this and so we don't have I guess it's when people don't want to worry about writing a constructor you just say I've got a public property that's a notifier and get rid of the constructor and let anyone set it so of course the problem we've got with this is that we lose all that safety of tightpints again we're back to the point where anyone can set the notifier property to anything they want so you could improve on that and say set your injection we should just get a bit more use which essentially what we're doing here is saying that we're back to a private property for the notifier but we're using instead of a construct method a setter method that says it looks the same as our constructor earlier it's saying set notifier to an install notifier and then it may use it a bit that way so there's a problem with this which is if we do this so we're creating a new stock levels class object from the class and then we're updating the stock levels but we've forgotten if we're using such an injection we do also need to call that setter method to give it the notifier so if we run that without making other changes to the class then we're going to find that we've got a null object so the problem with using setter injection setter injection is that you can kind of create a class or create an object from a class in an inconsistent way so in a way where it can then fail in use if we use the constructor injection we wouldn't have got into that situation and there's things you can do inside to make sure that's okay, you could say okay well I only want to notify people I don't always want to notify people so I'm going to make it an optional dependency and then say have I got this statement to say is there a notifier set on this property if there is call it if not don't so that's one of the kind of use cases of setter injection but I don't I wouldn't use it other than that and even then I would consider using like a null implementation of a notifier so we pass in a notifier that doesn't actually do anything but as far as the stock levels class is concerned it's exactly the same as if it had received one that did do something okay so about is it kind of at a class level is all there is to it but how it all works at an application level then does sort of change a bit and becomes interesting because part of the problem we have is not a problem but they're kind of knock on effect of this is that if we're taking all that creation of dependencies out of the individual classes then it has to go somewhere so whenever we say we've kind of had simple examples of I would just call new this the new one of those but as we go we kind of find well if we do this to all our classes so we only looked at stock levels before but in the email in stock notifier we're probably going to need to create we want to inject its dependencies instead of saying new emailer a new customer here we could change that and say actually I want you to give me a customer repository and I want you to give me an emailer service and then I'll make use of those properties rather than instantiating the time I use them and then if in our emailer sort of class we might want to make that an interface so we can switch between Swiftmailer and another emailer so again we introduce new emailer class got Swiftmailer we actually create the Swiftmailer object itself outside of that and pass it in perhaps rather than having that code in there to do the setting up and the new and if we do the same with customers of our doctrine customer repository it's an implementation of customers so we can swap it in and out again and we create the we want to create the doctrine entity manager somewhere else and pass it in so if we do all of this it makes instantiating a stock levels class quite a bit more difficult so it might be quite flexible but if we want to create one we might have all of this case we've got all that stuff saying here's the doctrine configuration here's the doctrine connection configuration we've got our mail server server port user name password we need to create an entity manager we need to create a Swiftmailer transport we need to create a Swiftmailer instance then we can start switching all of this stuff together so we can say new stock levels our new email in stock notifier for customer repository that has an entity manager and a Swiftmailer thing which takes a mailer so it's starting to get quite complicated just to set up all of these classes they might be nice and small but because we've separated that somewhere else in our application we now need to do all the object instantiation do all of this sort of stuff and then we can make use of it and what creates the stock level objects because whatever is using that probably isn't going to want to do all of that code we're probably going to want to actually create it push that up again create it somewhere else and inject it into that object so if we keep pushing all our dependencies up then we find its dependencies all the way up and they all kind of pop out the top of our application and we need to kind of create them all somewhere and then we can make use of it so when we have quite often with things like this we've got there are patterns that can help us deal with this so there's design patterns for this sort of thing so some of the ones that are around for construction that we could use things like builders and factories but nowadays there's a more specific objects sort of pattern that we can use which is that dependency injection container so this is like a container or sort of specific object or in the case of sort of symphonies one a collection of quite a lot of objects that work together to wire up all of our objects and then give it to us in this pre-wired state you might also hear it called the service container in the symphony world because we kind of think of these sort of objects for wiring up like our mailer and we call them services unfortunately services are horribly overloaded word in software engineering so in this case when we talk about services what we're talking about is those sort of objects we've seen pre-wired up that we can just make use of is also quite an overloaded word now particularly with sort of the docker being all the rage so this different use container for that so it's slightly unfortunate naming and you may also see elsewhere like people talking about IOC containers which essentially is just the same thing so IOC here stands for inversion of control and dependency injections like a specific way of achieving a bigger concept of IOC so the inversion of control is that we're taking away the control of deciding what to do from how to do it and pushing it outside and dependency injections is a good way of doing that if you're doing objects or into programming so in a small application if you're writing just maybe like a little command line tool or something like that and you start pulling your code apart in that kind of way it may not, you may just be able to have you've got a bootstrap file at the top you don't mind writing a few like stitching it together with a few new things as that grows and it becomes unmanagable it might be useful to introduce one of these containers so one for sort of smaller and medium size applications we can use is Pimple so with Pimple when we use it it looks something like this so this will be now like a sort of bootstrap file you could say I want a new container so it's a new Pimple and then I'm going to set myself services on that so it has like array access style access so we can say container stock levels is and then tell it how to create stock levels objects so we're kind of assigning like key style things to services so we can refer to them elsewhere and then we're actually kind of doing what it does is use as an anonymous function here to say when I ask for this actually then run this code so we're going to still do the same sort of thing and say a new stock levels thing and ask the container to give us the stock notify email service and create it with that so the reason for using anonymous functions for this sort of thing is as your application grows you may not want to instantiate every single object in it for every request or everything that you use it so by wrapping it in anonymous functions in this way we can just say only if I ask about a particular set of objects should you call that function and give them to me so particularly if you've got any objects heavy to construct it can be useful so we'd have to create something similar for the next level down so stock notify email email is itself an anonymous function that asks for its dependencies from the container and then we can kind of write that code for creating the Swiftmail stuff in there so it gives us a way of organising it and it also differs in the actual time of which you call new and all of it and do that and it also means that the container can keep track of all those things by a config key rather than you creating kind of variables and having to refer back to that particular variable so you could maybe then start to split this up across more than one file so you don't have to keep it all locally in local scope you can kind of set up some of the container in one place some of it in another place and not end up with one huge config file okay so at some point we actually need to get something out of it and make use of it so we might get a whole application or maybe a slightly lower level once you've decided which controller actions being run or which console commander you're using we're going to say give me the whole of that code for that particular key then I'm going to do something with it so at that point everything's all set up for us and then we actually start doing something and sending kind of our maybe console arguments or our HTTP request through the object graph so the pimple is quite simple and easy to understand if you ignore the little bit of noise of the anonymous functions in there then it's actually pretty similar to what we'd have written if we weren't using the container if we do have lots and lots of configs and a larger application and we probably don't want to write all of those sort of functions out so so in a larger application you can make use of a symphony service container or if you're using a symphony full stack framework and this is already there it's going to come with some of its own services set up and then similar I believe in Drupal 8 so here we can use config files rather than writing code in order to actually configure the different services there's a couple of ways different things available to you so you've got XML or YAML I need XML for the examples mainly because it is more of a boast it's more explicit, you can see what's happening with YAML, once you understand it it cuts it all down but you do kind of it loses that explicit you need to know that when you put certain things in the ray with a certain symbol in front of it it means this so in our XML file services the simplest thing we can do is just define like a service like this so again we give it an ID so this is similar to the Pimples kind of array access keys so we're saying we've got a stock level service with that ID and then the class is the actual PHP class here stock levels you could use namespace classes in here and put right out the full namespace so we're saying to a container when I ask for one of those use new on that stock levels class and then give that back to me of course we needed to have some arguments passed into that so our notify email so we can use the argument element to say it's an argument for you it's a service and here's the ID so this is another service and when you find somewhere else when you create a stock levels thing go and find that service, create that and inject it into me so it will kind of recurse through all of these definitions so our stock levels definition we could swap it that was for email if we wanted to use SMS we could just at this point swap it for the SMS service instead so that was that kind of instead of doing it in the code we're just changing an XML file external to the code okay so what you'd probably find so then we can create more services at this level so we're stitching together we add our stock levels our email in stock notify which takes the customer repository doctrine and then email swiftmailer in this other service it's the email swiftmail so it's all pretty straightforward then we will find though if we remember that to create a swiftmailer instance so this wasn't the code we're written it's from the library but we did that through a static method we called new instance and passed it with transport so we can still do this with the service container so it gets slightly more complicated now we can have so well as a class as a factory class of swiftmailer and a factory method of new instance so now the container will know that instead of calling new to create one of these objects it will create it will use swiftmailer new instance to create it and what the container will do is keep track of all these objects as well so it's not going to create a new one every time you ask for this each time it will say have I already got one of these if it has have that back if not now I'll create it and keep track of it so you effectively only ever get one instance of these each instance of these services so setting up the swiftmailer transport thing itself is a bit more complicated than that so here we had various config values in our code the mail server address port number the username and the password and then we again used a static method and we also called some methods on it so having got hold of the transport object we called setUserName and we also called setPassword to set that up so we can deal with the parameters by having a parameter section that's also supported in our config file so the parameters so we've got a key to give it a name that we can refer to and we set the value in there sort of statically and we can refer to that in our service definition so instead of saying our arguments are now another service we're saying it's using these percent signs it's the mail server variable so it will the service container will refer back to that parameter and put it in for us we could also just pass in static scalar values at this point and you can also set PHP like constants out of PHP classes as well we also needed to call a setUserName and setPassword methods on there so and our the service container can do this for us so after we've said the constructor arguments we want to pass to it we can also say here's some methods that we want to call so here's the first method is setUserName and here's the parameter that I want to pass to at the mailUserName parameter and then we can do the same setPassword in this case the parameters you could just pass yet more service in there so if you did want to use a set of injection you can use this as a way of passing services into all the services through setUserMethods so the advantage using like the symphony service container is that we're assembling files from various places so you can assemble your own files the framework itself will provide them so in fact if you're using a symphony framework you wouldn't need to do all this stuff with Swiftmail it's kind of taking care off for you and just opened up as a mail of service so it reads in your parameter files uses those to create those services and it's there for you and the various third party bundles and things that you can add also provide yet more services into the container so you can keep finding preset up things and they'll expose ways of configuring them passing different parameters or you can override the way it's done to stitch it up slightly differently so you don't have to write all of this config just the part safe as your services what it does mean then is that we're kind of like assembling stuff from various parameter files the party bundles the framework itself and taking all those XML files and stitching it all together so that the container knows about all sorts of services so one of the things it does do then is provide us with caching so the caching work essentially all that gets turned into PHP code and it all gets dumped into one file so that every time you kind of using the container firing up your application it just reads in that cached file and not all those XML files and YAML files and any files and things that are scattered around the file system because that would be quite a big performance hit there so it turns it all into one big PHP file which loads pretty quickly and essentially just contains PHP that look quite like the stuff we saw at the start where we just say new this, new that all the way through ok so how do we actually access services out of that we can call just the container has a getter method at the top container gets and give me a service by that service ID so we want to get a whole application out of it or individual controllers or in a controller get individual services but we should try and avoid as we get further down avoid doing that apart from when you have to write up at the top and what I mean by this is instead of we might end up and be tempted to instead of writing code like this where we've got the constructor passed in so the notify pass constructor is to do something like this and say I'm going to pass a container in and then I'm going to get the service out of there and it's tempting to do this but what happens then is that you're creating a dependency not on a notifier anymore but on a particular service container so you can't use this code with a different service container and we actually lose some of that kind of safety again because we're back to relying on the fact that the container was configured with something that implemented our in stock notifier interface but there's nothing inside this class that guarantees that anymore like if someone reconfigured the container we could get anything out of there so I think it's just fine it's really helpful to try and remember that what you're doing is assembling these classes in a simple way the container is there to help you put it all back together it's not rather than something you should actually rely on in the code itself okay so when do we actually use dependency injection this sort of way should we use it for everything and avoid constructing anything directly ever seeing the new keyword and just do it putting everything together in this sort of way well it's good for these sort of reusable stateless services so email it makes sense to pass in because we can use that over and over again once it's set up we can send as many emails as we want for it and it's not going to make any difference each time it will behave the same there's no side effects of using it likewise if it was something like a templating engine so if we're using twig for templating once it's set up we can render lots of templates with twig and we're not going to find that there's any problems doing that it should be the same every time or a router service that generates URL for us for instance so but we do have other things like this in our application so if you've got values that represent things or entities then each one of those is different we don't want one whole application we don't have one customer we have lots of customers hopefully so these are the sort of things we should create directly so each email message is different to the previous ones and we'll still see new keywords perhaps for those if it's a product when we're creating it, product has identity based on its on its skew it's not the same as we can't have one reusable product object customers same sort of thing we may not use new maybe we've got a named constructor that people quite like using nowadays we're using a static method to do that so we're saying customer register this it's still creating a new instance each time so we're not going to use DI for everything but for anything where it does make sense that is that kind of configurable service that we're going to make use of then I like to try to make sure it's used for everything and push everything right out of our application and configure it to somewhere else because as soon as we're not doing that we're tying ourselves into specific implementations okay and when should we use a container so if you're writing a small app that's growing when it becomes too difficult to manage those dependencies directly so whilst you've still only got like a small amount you can kind of keep on screen and keep track of there's no need to introduce complexity of using a dependency injection container once it starts to grow and become unwieldy and you don't want to create everything every time you want to be able to split it up into lots of different files and configure them separately then it makes sense to start using a container and the other thing time of course is if you're using a frame if you're using a full start framework like symphony or using something like Drupal 8 which will use the symphony service container then the container is already going to be that it's already providing services for you so you could use it in a way by saying you should try and avoid and say okay give me the container give me a service to create your own classes that make use of those services and tell the service container how to create them using those services that are already there for you so you tell it that you want to use a mail service rather than saying hey give me the mail the service out of the container so the main things for me is the kind of very important about dependency injection but it is very simple really as a pattern for creating objects there's not very much to it really but you should use constructor injection where possible you can use setter injection and property injection things like this but you lose some of the type safety documentation you get from using typepins and you also get this potential for objects to end up in inconsistent states and it also means you know that once it's constructed it stays the same if you're using something like setter injection then some of the bit of code in your application can change those dependencies under you at one point and then call it again and find that the behavior is changing between constructor injection gives you a form of immutability that means that once you set your services up how you want them to be set up they'll stay set up that way for that request and the other thing is that containers for assembling code only if they're not there to be used throughout the application they're there to help you with a specific problem of how you put all those objects back together okay that's what I've got to say today so thank you time for questions in a minute I just need to say a couple of things which was to promote the sprints on Friday so and I also need to say that so iCOS which is a sort of like a sister company of Central Ireland UK now with both parts the same group is running beers at the booth along with Lingo Tech at that booth tomorrow afternoon about half free so that's a booth 303 where there will be free drinks and snacks okay and you can evaluate this session of this URL here okay cool so does anyone have any questions at all yes yes so the question was can you use dependency injection in legacy applications and wrap them in that so yes you can certainly introduce it and there's certain things you can do so because you can still create your instances of objects of a legacy code it might be that then underneath them they create their own but you can kind of you could create the higher level objects in the container and start to work with it that way rather than you don't have to go full you know whole scale get everything out inject it back in and once you're getting the kind of higher level objects out of the container you can then start to refactor those in a way that the rest of the code doesn't say no about it just knows it gets one of those an instance of your legacy object and can start using it so in your new code you could start using it there you could also can start to I mean I wouldn't do it with new code but you could do things like wrap kind of a way of having static access to the container into your legacy code so you can sort of pull dependencies out of it at different points in that even though you haven't refactored the whole thing to use dependency injection so anyone else well thank you