SitePoint Sponsor

User Tag List

Page 2 of 3 FirstFirst 123 LastLast
Results 26 to 50 of 66
  1. #26
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by kyberfabrikken
    I believe that the php-version of pico-container is based off of phemto?
    Not at all. Pawel had ported the PHP Pico from the java version long before I had even an elementary understanding of the concept. Both Pawel and myself want to develop Phemto as well, as a super lightweight introductory DI tool, but time hasn't allowed yet.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  2. #27
    SitePoint Zealot
    Join Date
    Jul 2005
    Posts
    194
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Looks nice! I have re-implementated my code from above, and made it more like your solution but then for PHP5. Works nice. Thanks. Hope you don't mind, though.

  3. #28
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by lastcraft
    Both Pawel and myself want to develop Phemto as well, as a super lightweight introductory DI tool, but time hasn't allowed yet.
    Ah. I see. Would you care to explain the differences between phemto and pico ? I haven't completely grasped all the details of the implementation of pico myself.

  4. #29
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by kyberfabrikken
    Ah. I see. Would you care to explain the differences between phemto and pico ? I haven't completely grasped all the details of the implementation of pico myself.
    I have actually been deliberately not looking at Pico to see if I can develop something independent. I'll probably cave in soon though fo rthe sake of finishing the project off. PIco has setter injection and the ability to add decorators for AOP like effects. Probably lot's of other stuff as well.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  5. #30
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I stumbled over this blogpost, which refers to Fowlers article :
    http://www.betaversion.org/~stefano/linotype/news/38/

    He makes a IMHO quite valid point with :
    Martin Fowler renames it (IoC) Dependency Injection, and, in my opinion, misses the point: IoC is about enforcing isolation, not about injecting dependencies. The need to inject dependencies is an effect of the need to increase isolation in order to improve reuse, it is not a primary cause of the pattern.

  6. #31
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well I'll be the first to admit that I don't fully understand IoC or DI or AOP. I read these articles and get glimpses of the concepts that they are writing about. However I do know the real-world problems that I have that I think relate to these concepts. I thought that if I showed the couple of common problems there are in PHP that might be solved with these concepts it might make them clearer to others (an they might present better solutions than I currently have to these problems ).

    AOP - The term crosscutting concerns often comes up related to this. I think the major application I have for this in PHP is for Access Control. Access Control is a strange problem because a bunch of pages across my sites need to do (sometimes all, many or only a fewl) and I usually find the code clunky. Worse, when the Access Control system needs to changes to increase or decrease the complexity of the Access Control system it is usually a pain to make the change because the calls are everywhere. What you really want is a system that just magically works and can be set and controlled from outside your code so it becomes and "aspect" rather than part of the code. AOP could help to let you specify general access centrally and still have fine grained access information available where needed.

    IoC/DI - I'm still not clear what the words Dependency Injection really mean when put together, but I do know that there are a number of object that I would really like available in lots of places in my code and I get sick of having to pass them around to get them there. I may get the dependencies to be clean and pure, but the code just annoys me. Probably the to most common object that I have like this are Configuration, Template and DBConnection. There is usually on one of each in most of my sites.

    A Configuration object make it easy to change the source of the config data and I find defines a pain to manage. Multiple template systems would drive me crazy so I only want one. Whereas multiple DB connection are pretty easy to handle and it is fairly common to connect to a local database of one kind and a remote database of another.

    What I want to do is just get a Template and DBConnection object when I need it with a simple $template = ???->get('template'); and go about my business. These objects are needed in every View and Model (Template and DBConnection respectively) and I really don't want to clutter up my code with constructing them. DBConnection is particularly annoying because it uses configuration information for the connection so that has to be available as well.

    So I don't think there are many uses in PHP for IoC/DI/AOP, but the few that that exist are very common.
    Christopher

  7. #32
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    As the blogpost I linked to above suggests, the term Dependency Injection can be confusing.
    The problem to solve is that of concrete class dependency; Class Car depends on the concrete class Engine. The strategy to solve it could be one of two types of Inversion of Control.
    • The first is thorugh a ServiceLocator; You pass a factory (ServiceLocator) to the Car.
    • The second is through Dependency Injection; Here instead, you pass the Engine to the Car, rather than let the Car create the Engine itself.


    In both of theese cases, the Car changes from depending on a concrete class (Engine) to depend on an interface (IEngine). Thus the problem has been solved.

    As such, you don't really need a tool (such as pico) in order to do Dependency Injection. The tool just automates the process. So you can say that pico is an instrument to provide Dependency Injection. And Dependency Injection is a means for removing concrete class dependency.
    Last edited by kyberfabrikken; Aug 1, 2005 at 02:28.

  8. #33
    SitePoint Zealot
    Join Date
    Jul 2005
    Posts
    194
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    hmm, if I understand it all correctly, you could use Dependency Injection for adding Authorization/Authenication support ?

  9. #34
    SitePoint Addict timvw's Avatar
    Join Date
    Jan 2005
    Location
    Belgium
    Posts
    354
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The hardest part is to come up with an interface and implementation of your Authentication and Authorization..

    Once you have done that, there are various methods to pass instances of the classes. Where DI is one of them.

  10. #35
    SitePoint Enthusiast
    Join Date
    Jun 2004
    Location
    Stillwater, MN
    Posts
    96
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I don't see how
    PHP Code:
    class Car {
        var 
    $engine;
        function 
    Car($serviceLocator) {
            
    $this->engine $serviceLocator->createEngine();
        }

    is any better than
    PHP Code:
    class Car {
        var 
    $engine;
        function 
    Car($engine) {
            
    $this->engine $engine;
        }

    Did you mean to use a static method?
    PHP Code:
    class Car {
        var 
    $engine;
        function 
    Car() {
            
    $this->engine ServiceLocator::createEngine();
        }


  11. #36
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Radley
    I don't see how
    PHP Code:
    function Car($serviceLocator) {
            
    $this->engine $serviceLocator->createEngine();
        } 
    is any better than
    PHP Code:
        function Car($engine) {
            
    $this->engine $engine;
        } 
    In the above case, a class that creates the Car doesn't need to know what the Car needs - it provides a ServiceLocator for that. This uncouples their relationship. Compare this to the class knowing that the Car needs an engine. How about if you want to change that to an engine and a set of wheels? By the very least you'd be bound to change the construction arguments wherever the Car is used.

  12. #37
    SitePoint Zealot
    Join Date
    Jul 2005
    Posts
    194
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Aha, yes I will still have to come up with something.

  13. #38
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Radley
    Did you mean to use a static method?
    Oh no.

    Quote Originally Posted by Radley
    I don't see how <Service Locator> is any better than <Passing-in the dependant>
    It's not necessarily. Service Locator is an alternative to Dependency Injection.

    As Ezku explained, passing-in the dependant moves the coupling out of the subject class and into the calling class. To completely remove the coupling, you will have to pass the object all the way from the global scope. In a simple setup, this isn't much of a problem, but with a complex application, there will be an overhead in terms of passing a lot of objects through method-calls / constructors. An automated Dependency Injector takes care of this overhead for you.

    ServiceLocator is an alternatively solution, which of course also needs to be passed from the global scope, but there is just one instance to pass for your whole application. Thus the overhead is reduced to one. Compare this to the Dependency Injector, which reduce the overhead to 0.

    Another weakness of the Service Locator is that it itself will have concrete class dependency and thus be hard to test. This is normally considered acceptable - at least it's better to have just one point of concrete class dependency than have it scattered all over the application.
    Last edited by kyberfabrikken; Aug 1, 2005 at 07:10.

  14. #39
    SitePoint Addict timvw's Avatar
    Join Date
    Jan 2005
    Location
    Belgium
    Posts
    354
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Radley
    I don't see how
    PHP Code:
    class Car {
        var 
    $engine;
        function 
    Car($serviceLocator) {
            
    $this->engine $serviceLocator->createEngine();
        }

    is any better than
    PHP Code:
    class Car {
        var 
    $engine;
        function 
    Car($engine) {
            
    $this->engine $engine;
        }

    Did you mean to use a static method?
    PHP Code:
    class Car {
        var 
    $engine;
        function 
    Car() {
            
    $this->engine ServiceLocator::createEngine();
        }

    That is ok. Because, it's impossible to see


    They are all solutions to avoid the situation below where you bind Car to an explicit implementation of an Engine..

    PHP Code:
    class Car {
      function 
    Car() {
         
    $this->engine = new Engine// this would make the Car depend on Engine and can be a pita if you want to V8Engine instead
      
    }


  15. #40
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken
    with a complex application, there will be an overhead in terms of passing a lot of objects through method-calls / constructors.
    Just to illustrate the overhead-problem :
    PHP Code:
    class Engine
    {
    }

    class 
    Car 
        var 
    $engine
        function 
    Car($engine) { 
            
    $this->engine $engine
        } 


    class 
    Driver
    {
        var 
    $car;
        function 
    Driver($car) {
            
    $this->car $car;
        }
    }

    $driver = new Driver(new Car(new Engine())); 
    The constructor for Driver has become rather heavy at this point. It could get even worse, as you could imagine.

    Service Locator reduces this to :
    PHP Code:
    $driver = new Driver($serviceLocator); 
    While Dependency Injection makes it into :
    PHP Code:
    $driver $di->create('Car'); 
    Both a lot prettier than new Driver(new Car(new Engine()));

  16. #41
    SitePoint Member
    Join Date
    Apr 2005
    Posts
    5
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Does anyone have any comments on the performance of DI solutions in PHP?

    I'm a huge fan of the Spring framework for my Java work and so am familiar with the advantages of Dependency Injection, however in Java the configuration of the dependencies gets loaded only once with the instanciation of the Servlet, whereas in PHP this configuration would have to be loaded for every page request, once you get past the trivial examples I would imagine that parsing this configuration could begin to take a fair amount of time, not a hit I want to be taking on every page request.

    Is this a genuine concern or am I being too anal over processing time?

  17. #42
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi.

    Dependency injection in PHP doesn't involve XML as far as I am aware (Pico). If it did, you would code gen. it into PHP and use an accelerator anyway. No need to worry.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  18. #43
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I've recently played with the following:

    PHP Code:
    class ImplementationNotFoundException 
        
    extends Exception {};

    function 
    implementationOf($interface) {
        
    array_shift($params func_get_args());
        foreach(
    array_reverse(get_declared_classes()) as $klass)
            if((
    $ii class_implements($klass)) && isset($ii[$interface]))
                return 
    call_user_func_array(
                    array(new 
    ReflectionClass($klass), 'newInstance'),
                    
    $params);
        throw new 
    ImplementationNotFoundException();

    Example:
    PHP Code:
    interface IEngine {/* stub */}
    interface 
    IDriver {/* stub */}

    class 
    ConcreteEngine implements IEngine {
        function 
    __construct($power) {
            
    $this->power $power;
    }}

    class 
    ConcreteDriver implements IDriver {
        function 
    __construct($name$skill) {
            
    $this->name $name;
            
    $this->skill $skill;
    }}

    class 
    Car  {
        function 
    __construct() {
            
    $this->engine implementationOf("IEngine""333hp");
            
    $this->driver implementationOf("IDriver""John""Level3");
    }}

    var_dump(new Car());

    class 
    ConcreteEngine_NewVersion 
        
    implements IEngine {}

    var_dump(new Car()); 
    Not sure if this is Injection or Locator though.

  19. #44
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by stereofrog
    Not sure if this is Injection or Locator though.
    You're pulling the dependecies from within the subject object, thus making it depending on the implementationOf() function. I'd say that's a (static) ServiceLocator.
    The fact that you're using interfaces as identifiers for the dependencies doesn't really change anything.

  20. #45
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Isn't that exactly what you said above
    The result is again that Car has no dependency on Engine - instead it has a dependency on the interface IEngine - and dependencies on interfaces are not a problem.
    Could you please elaborate?

  21. #46
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by stereofrog
    Could you please elaborate?
    In your implementation, Car does not depend on IEngine. It depends on the function implementationOf(). Nothing more.
    You can mock the Engine class by replacing the servicelocator (~ implementationOf) with something else. (except you have made it static, so it may be tricky).

  22. #47
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Eh? I can mock Engine by declaring something other that implements IEngine. Client (Car) will just use (lexically) last implementation of the interface. Neither Car itself nor implementationOf() needs to be changed:

    PHP Code:
    class RealEngine implements IEngine {}
    ...
    class 
    Car
    ... $this->engine implementationOf("IEngine"...

    // testCar uses TestEngine
    class TestEngine implements IEngine {}
    $testCar = new Car(); 

  23. #48
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by stereofrog
    Neither Car itself nor implementationOf() needs to be changed
    I understand, but you're missing the point. You need to look at which dependencies Car has. In your example, Car doesn't depend on Engine and Driver. Instead it depends on implementationOf(). Looking solely at the Car class, the only dependency is on implementationOf().

    If we modified your code, so the servicelocator is no longer static, it may be easier to see :
    PHP Code:
    class Car
    {
        function 
    __construct($factory) {
            
    $this->engine $factory->implementationOf("IEngine""333hp"); 
            
    $this->driver $factory->implementationOf("IDriver""John""Level3"); 
        }
    }

    class 
    DefaultServiceLocator
    {
        function 
    implementationOf($interface) {
            
    // (copy from post #43)
        
    }
    }

    $car = new Car(new DefaultServiceLocator()); 

  24. #49
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ah, ok, I see that now. This is pretty much what Fowler says
    The key difference is that with a Service Locator every user of a service has a dependency to the locator. The locator can hide dependencies to other implementations, but you do need to see the locator.
    Thanks for the patience.

  25. #50
    SitePoint Zealot
    Join Date
    Jul 2005
    Posts
    194
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    After searching for some information about usability, I came on the site of Alfresco. It's really nice, made by one of people behind Documentum. Now I also read their whitepaper and I got a question about that... let's quote.

    In the AOP approach, a system uses a pattern of development called Dependency Injection.
    Dependency Injection is to take method on an interface, such as fetch or save, and to inject a handler
    that does additional processing either before, after or instead of the standard call. For instance, to add a
    read lock on a content object, we could make a lock call before a fetch and an unlock call after a save
    or release call.
    The calling application should not be aware whether a read lock has been added or not,
    so the dependency injection should be automatic and not require any additional programming.

    The Spring Framework provides us with the ability to wire in these automatic behaviors as a configuration
    exercise rather than add code at all the places we need to use it. Transaction control is an example of a
    capability that can be added in without programming and providing us with robust control of content.
    In addition, we use a number of essential services by merely configuring the service aspects in, such as:
    transactions, n-tier partitioning, caching, web service calls, authentication, and service call
    authorization.
    Of course the emphasized part really sounds interesting, how would I do this? Anyone got a idea? Because I am not sure if the above is possible to do this, but I will look into that myself first thing tomorrow morning.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •