The SitePoint Forums have moved.

You can now find them here.
This forum is now closed to new posts, but you can browse existing content.
You can find out more information about the move and how to open a new account (if necessary) here.
If you get stuck you can get support by emailing forums@sitepoint.com

If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

The smallest dependency injector?

Hi.

As a result of an article for PHP|Architect I have finally gotten a chance to play with dependency injection and the result is called "Phemto". It's the bare minimum of a dependency injector as I understand it. I am sure that I have missed some vital feature that Jason, et al. will tell me about. It only works with PHP5.

That is the wiring can be done purely by interfaces and is handled by typed constructors. As usual when I post code on the forum, it's a plaything that anyone is welcome to carry forward. Idon't advise using it in the real world though .

So what is the killer app for a dependency injection container in PHP.

I have absolutely no idea .

Given that a PHP "program" is just a small slice of the application, the construction needs shouldn't be that great, right? No need for complicated wiring and all that? Well, I now have a kind of half idea that I may have been missing out on something.

The injector seems to be of most use for wiring up large chunks of application when the authors of these chunks are constantly changing their dependencies on each other. By giving each other interfaces (or writing adapters) you can gather together say a catalog, a store backend and a shopping cart without having to see the actual code at all. You don't have to see the constructors of these objects either and thus you know nothing of their dependencies as long as you can satisfy each one on demand.

Because of the constructor passing, the components don't know anything about the injector either, they just have to follow the rules for that injector. In the case of Phemto, everything in the constructor with a type hint.

Is this any use? I have no idea. I have never tried it or yet needed to.

It's currently just a curiosity to me. To make it useful in a real program anyway, you would have to add Injector::registerAsSingleton() and, especially for PHP, Injector::registerAsSession(). I would also want to allow superclass specifications, rather than just interfaces, for completeness. It's currently only 50 lines of code after all.

Nice work, although it's not very clear to me, why if you register two classes (that implement the same interface) and then create the interface, you get the latter one. I mean, I see why it works like that, since in the register method, a class is saved in the hash with the interface name, so the latter class 'overrides' the former. What I don't understand is, why is it so? Does it have to be like that? Is constructing a class by passing the interface name to the injector usable at all?

Nice work, although it's not very clear to me, why if you register two classes (that implement the same interface) and then create the interface, you get the latter one. I mean, I see why it works like that, since in the register method, a class is saved in the hash with the interface name, so the latter class 'overrides' the former. What I don't understand is, why is it so? Does it have to be like that? Is constructing a class by passing the interface name to the injector usable at all?

Regards,
f

I think your only meant to register only one implementation of any given interface.

the code looks impressively clean. i still haven't completely understood what the use for dependency injections is, but well ... seems to be a common problem though ?

Funnily, the more I am aware of it, the more (potentially) useful it seems to become. Take this hypothetical example. I have a class, that I'll call Gateway, that is created in a complicated web page that I want to test. I am using a web tester for this test, so mocking it out is not an option. I would like to use a server stub though to emulate behaviour for the rest of the script. Trouble is this runs in a separate process than the test, so how to get the stub in?

If the search order is to look for session objects first, then the StubGateway will fill the dependency first in the live script.

Probably not a good example, but I do get the feeling that there is something to the DI stuff after all. I'm still groping. Other lifecycle options might be shared memory, or even automatic stubbing for the trick above. It's the way the lifecycle is defines outside of the client code which is the other half of the DI puzzle I think.

Funnily, the more I am aware of it, the more (potentially) useful it seems to become.

Im pretty skeptical about dependency injection containers (Would that or things like Pico be called a container?). I can see where it could be very usefull for the reasons already mentioned however it seems to me there are some big hurdles to using one.

Object creation isnt as simple as laid out in most DI examples. Usually creation of objects is hidden behind some sort of creational method. This means as already mentioned that the Injector would need to be a singleton (Kind of goes against the entire DI priciple ) or passed into the object (Dont really like this idea either as it dirties the interface).

On top of being hidden behind factories objects are rarely constructed like this:

PHP Code:

$object = new Object(new ObjectB(), new ObjectC(new Object D()));

They are constructed using objects that have been built during the process of the script. They use request variables, configuration file variables, etc in their construction parameters.

For some reason the idea seems to break down and become more trouble than its worth. I could be and hope Im wrong though, because the theory behind it should enable you to make dependency changes much easier, and thats always good.

I think it would be good in a system, where there may be a range of objects that focus on one task, run pretty much the same, but are different in their naming.

So instead of going through all of your code, you could just write two or three lines in the beginning that would create a register for say a class to communicate with the database.

This would also make it easier if someone had set up a pgsql and mysql class, but didn't write them in a way that they we're easily swapped with a configuration setting. Although the example isn't that good it does show when it can be a good thing to use something like DI.

I don't really see it in a situation where you change the dependency and this also breaks the code. But that's just my take on it.

So instead of going through all of your code, you could just write two or three lines in the beginning that would create a register for say a class to communicate with the database.

This is an interesting "dependency injection" like pattern that keeps cropping up in various MVC frameworks, where one will stuff a database connection into the request object in an intercepting filter. See this thread:

Global filters are good for setting up database objects, for example. You perform all the code to connect to the database and instantiate a db connection object. The way you get this to your Actions is by putting it in the $request object in the filter and retrieving it in your actions (see $request->setAttributeByRef(), $request->setAttribute() and $request->getAttribute()).

This is an interesting "dependency injection" like pattern that keeps cropping up in various MVC frameworks, where one will stuff a database connection into the request object in an intercepting filter.

Ewwww! And "keeps cropping up" implies you have seen this more than once?!?

Originally Posted by Brenden Vickery

On top of being hidden behind factories objects are rarely constructed like this:

PHP Code:

$object = new Object(new ObjectB(), new ObjectC(new Object D()));

No...but it could be I think the DI pattern may make you want to put your thinking cap on a little askew. Whereas when you are coding up things by hand, passing in to many different objects in the constructor is a bit of a pain, but when you ask for an object, which as another object which was constructed with two other objects from the DI container, and it just hands it to you, it puts things in a slightly different perspective.

You can see some of my efforts at combining WACT and Pico here. All I have used it for is to "auto-wire" the application to run, and allow for injection of MockObjects during testing.

No...but it could be I think the DI pattern may make you want to put your thinking cap on a little askew.

I like putting my thinking cap on askew. Maybe you guys can help me here.

The example from Fowlers article is, as he admits, a naive example. "Super simple, small enough to be unreal". But Ill use it anyway. Here is his test case converted to php/simpletest using pico contatiner.

If I had a pico expert beside me here is what I would ask:
- Am I supposed to be passing pico to all my objects like it is a huge factory?
- Am I supposed to be making multiple instances of pico all over my code?
- Am I only supposed to be using pico in my tests?
- How do I deal with objects that need to be created using objects that have already been constructed (eg. Not just class names but real objects that need to be passed into the constuctor).

Ewwww! And "keeps cropping up" implies you have seen this more than once?!?

Well, the thing is that passing the database connection to the action instead of a singleton may be a good thing. Crufty java inspired implementation aside, perhaps this is part of the "killer application" for dependency injection.

Ever since that picoContainer thread, I've had a hunch that there was a dependency injection container hidden somewhere in the WACT Handle class. I just don't know where yet.

It is interesting that some of the examples look as much like a Service Locator as Dependency Injection. Both provide a path to Inversion of Control. Fowler seems positive on both Service Locator and Dependency Injection, and definitely likes Service Locator's simplicity. I wonder if Service Locator might be a better path in PHP given the lack of plumbing (short of a C extension) to support Dependency Injection as done in Java.

Given that Service Locator is described as both a subset of Dependency Injection and easier to implement, when are they applicable in PHP?

It seems that with the PHP Request/Response cycle only executing a small slice of the whole application that the disadvantages of Service Locator in that you need to pass the object around are minimal. Current PHP frameworks already pass a Request object about as many places. Why not just replace the Request object with a Service Locator object and at a minimum register the Request object with the Service Locator. Quick example: