|
|||||||
New to SitePoint Forums? Register here for free!
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 |
|
SitePoint Victim
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Apr 2003
Location: London
Posts: 2,273
|
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. Here is a sample piece of usage... PHP Code:
.yours, Marcus |
|
|
|
|
|
#2 |
|
SitePoint Guru
![]() ![]() ![]() ![]() ![]() Join Date: Nov 2002
Posts: 848
|
So what is the killer app for a dependency injection container in PHP. (versus manual dependency injection.)
I can't give you any more rep, Marcus. ![]() |
|
|
|
|
|
#3 | |
|
SitePoint Victim
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Apr 2003
Location: London
Posts: 2,273
|
Hi...
Quote:
.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. I do have a vague feeling it could be useful... yours, Marcus |
|
|
|
|
|
|
#4 | |
|
Non-Member
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jan 2003
Posts: 5,799
|
Off Topic: Quote:
But I can ![]() |
|
|
|
|
|
|
#5 |
|
SitePoint Mentor
![]() ![]() Join Date: Jun 2004
Location: Copenhagen, Denmark
Posts: 5,916
|
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 ?
|
|
|
|
|
|
#6 |
|
SitePoint Guru
![]() ![]() ![]() ![]() ![]() Join Date: Dec 2004
Location: ljubljana, slovenia
Posts: 678
|
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 |
|
|
|
|
|
#7 | |
|
SitePoint Guru
![]() ![]() ![]() ![]() ![]() Join Date: Aug 2003
Location: UK
Posts: 969
|
Quote:
Think I'd remove the dynamic code building/eval(), using ReflectionClass::newInstance() $reflection = new ReflectionClass($class); $object = call_user_func_array(array($relection, 'newInstance'), $objects); Wouldn't this also need recursion protection, if a class deeper the construction depended on something higher? Probably shouldn't happen in a well designed application, but it'd be good to make sure. |
|
|
|
|
|
|
#8 |
|
Non-Member
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jan 2003
Posts: 5,799
|
Yer, I have a hard time following this as well, but maybe someone can gleam something more from this image I've attached?
I've proberly had the need for this but not realised it myself, what I could do with is more examples... Hint, hint ![]() |
|
|
|
|
|
#9 | |
|
SitePoint Victim
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Apr 2003
Location: London
Posts: 2,273
|
Hi...
Quote:
Suppose the test script does this... PHP Code:
PHP Code:
PHP Code:
PHP Code:
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. yours, Marcus p.s. that is "Dependency Injection", not "Dependency Inversion" . |
|
|
|
|
|
|
#10 |
|
Non-Member
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jan 2003
Posts: 5,799
|
What? They're not the same then?
![]() |
|
|
|
|
|
#11 | |
|
SitePoint Addict
![]() ![]() ![]() Join Date: May 2003
Location: Calgary, Alberta, Canada
Posts: 277
|
Quote:
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:
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. |
|
|
|
|
|
|
#12 | |
|
SitePoint Victim
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Apr 2003
Location: London
Posts: 2,273
|
Hi...
Quote:
Does anyone have any experience using DI tools? Everyone (me included) seems to be judging something that we have no personal experience of .yours, Marcus |
|
|
|
|
|
|
#13 | |
|
SitePoint Addict
![]() ![]() ![]() Join Date: May 2003
Location: Calgary, Alberta, Canada
Posts: 277
|
Quote:
. I have no experience using one. Hopefully we will all get a chance to use Pawel's port of pico soon though. |
|
|
|
|
|
|
#14 |
|
SitePoint Enthusiast
![]() Join Date: Jan 2005
Location: Sydney
Posts: 43
|
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. |
|
|
|
|
|
#15 | ||
|
SitePoint Guru
![]() ![]() ![]() ![]() ![]() Join Date: Nov 2002
Posts: 848
|
Quote:
Quote:
|
||
|
|
|
|
|
#16 | ||
|
eschew sesquipedalians
![]() ![]() Join Date: Jun 2003
Location: Iowa, USA
Posts: 3,779
|
Quote:
And "keeps cropping up" implies you have seen this more than once?!?Quote:
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. |
||
|
|
|
|
|
#17 | |
|
SitePoint Addict
![]() ![]() ![]() Join Date: May 2003
Location: Calgary, Alberta, Canada
Posts: 277
|
Quote:
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. PHP Code:
PHP Code:
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). |
|
|
|
|
|
|
#18 | |
|
SitePoint Guru
![]() ![]() ![]() ![]() ![]() Join Date: Nov 2002
Posts: 848
|
Quote:
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. |
|
|
|
|
|
|
#19 | |
|
SitePoint Wizard
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Aug 2004
Location: California
Posts: 1,672
|
Quote:
|
|
|
|
|
|
|
#20 |
|
SitePoint Guru
![]() ![]() ![]() ![]() ![]() Join Date: Nov 2002
Posts: 848
|
Possibly related: Singleton registry
|
|
|
|
|
|
#21 |
|
eschew sesquipedalians
![]() ![]() Join Date: Jun 2003
Location: Iowa, USA
Posts: 3,779
|
Unfortunatly, the need for the project I was working on with WACT and Pico evaporated before I completed the project, and a new project of similar complexity has not come along yet.
Here is where I got to (remember this is basically initial experimentation, not a well factored design ).a bootstrap file: PHP Code:
Here was the ApplicationController. Static calls, so more of just a namespace thing: PHP Code:
use a LazyLoading Proxy which remembers the PicoContainer.So an action might need a model and the request: PHP Code:
PHP Code:
PHP Code:
|
|
|
|
|
|
#22 | |
|
eschew sesquipedalians
![]() ![]() Join Date: Jun 2003
Location: Iowa, USA
Posts: 3,779
|
Quote:
![]() |
|
|
|
|
|
|
#23 | |
|
Non-Member
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jan 2003
Posts: 5,799
|
SweatJe, interesting concepts you have, indeed
![]() I don't like the idea either of putting objects into the request, this I feel is a bit suspect in my mind. Quote:
![]() |
|
|
|
|
|
|
#24 | |
|
SitePoint Victim
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Apr 2003
Location: London
Posts: 2,273
|
Hi...
Quote:
yours, Marcus |
|
|
|
|
|
|
#25 | |
|
SitePoint Wizard
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Aug 2004
Location: California
Posts: 1,672
|
Quote:
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: PHP Code:
PHP Code:
PHP Code:
PHP Code:
PHP Code:
|
|
|
|
|
![]() |
| Bookmarks |
«
Previous Thread
|
Next Thread
»
| Thread Tools | |
| Display Modes | |
|
|
|
All times are GMT -7. The time now is 22:05.




.







And "keeps cropping up" implies you have seen this more than once?!?
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.



Linear Mode
