SitePoint Sponsor

User Tag List

Page 2 of 3 FirstFirst 123 LastLast
Results 26 to 50 of 52
  1. #26
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    PHP Code:
    $injector->use('SmtpMailGateway')->with('LoggingMailGateway'); 
    sounds nice to me. It has the additional implications of being able to merely "use" something and only optionally bind it to something else.

  2. #27
    SitePoint Wizard
    Join Date
    Jan 2005
    Location
    blahblahblah
    Posts
    1,447
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi,

    How should I redesign my classes to make the following scenario:
    PHP Code:
    class Foo{

      public function 
    Test($var){

        
    //switch $var
        //case: 'blah' -> require/instantiate Blah(). 
        //case: 'blahvar' -> require/instantiate BlahVar().  
        //case: 'blahfoo' -> require/instantiate BlahFoo(). 

      
    }


    Should I instantiate all the objects. and then only use the one that is required?

    Regards,

    -jj.

  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 jjshell View Post
    Should I instantiate all the objects. and then only use the one that is required?
    If your object instantiates other objects, depending on a run time condition, then you are looking at a factory. You'll generally have few of those, but you may have some. If the objects you instantiate are sufficiently small (Eg. Don't have any dependencies), you can simply instantiate them with the new operator. If they need dependencies, then your factory will need to hold on to the container and use that for creating the instances. That's also fine, if you need it, but then you should make sure that your factory is just that - don't mix application logic into the factory.

  4. #29
    SitePoint Wizard
    Join Date
    Jan 2005
    Location
    blahblahblah
    Posts
    1,447
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks

    But what about lazy instantiation?

    PHP Code:
    if(!$var){
      return 
    false;
    }else{
      
    //new object created.
      //do some stuff


  5. #30
    ********* 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 View Post
    Oh .. and how a bout provide:
    PHP Code:
    $injector->for('LoggingMailGateway')->provide('SmtpMailGateway'); 
    Slightly different semantic, but still meaningful.
    Yes! And given you are a non-native English speaker, quite brilliant.

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

  6. #31
    SitePoint Addict
    Join Date
    Dec 2007
    Posts
    348
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    where can I download phemto? it doesn't seem to be in any of your signatures, or is still in a development stage?

  7. #32
    ********* 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 old_iron View Post
    where can I download phemto? it doesn't seem to be in any of your signatures, or is still in a development stage?
    Yes.

    It's a sourceforge project and you should fetch the CVS version:
    Code:
    cvs -z3 -d:pserver:anonymous@phemto.cvs.sourceforge.net:/cvsroot/phemto co -P phemto
    The only docs are the test cases .

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

  8. #33
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    There's now a basic website, including some docs, here: http://phemto.sourceforge.net/index.php.

    Note that we've just switched from cvs to subversion. Checkout with:

    svn co https://phemto.svn.sourceforge.net/svnroot/phemto/trunk phemto
    Last edited by McGruff; Oct 27, 2008 at 07:53.

  9. #34
    SitePoint Wizard
    Join Date
    Jan 2005
    Location
    blahblahblah
    Posts
    1,447
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Finally!

  10. #35
    SitePoint Wizard
    Join Date
    Jan 2005
    Location
    blahblahblah
    Posts
    1,447
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The documentation is really clear, and straight to the point.

    I have one or two questions though. Let me start with:
    If you want an object to have a singleton lifecycle:

    <?php

    $phemto->register(new Singleton('Charm'));
    What would a singleton lifecycle bring that a "regular" lifecylce does not? I mean, I can't figure out why I should singletonize an object or not.

    Thank you all for your patience .

  11. #36
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This just means that every time you ask for an object (or when phemto passes it to a client behind the scenes) it's always the same instance. For example a Request object is usually passed around to several other objects. They must all access the same instance of Request. Or perhaps a PurchaseOrder passes through several processing stages in the script, each new client manipulating the order in some way. That's the kind of thing for which you need a singleton lifecycle.

    Any object can be singleton-ised. The container handles that without requiring any changes to your own classes.

    Sometimes it doesn't matter whether an object is singleton or not and I find myself using singletons simply because it's more convenient to pass (scalar) parameters at the registration stage rather than later on in the app, wherever the object is pulled out of the container.

    Edit: objects are singleton-ised with respect to their parent container (phemto) not the script as a whole. If you have two or more containers on the go, and each has registered a singleton Foo, it will be a different Foo per container.

  12. #37
    SitePoint Addict
    Join Date
    Feb 2007
    Posts
    251
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You use singletons whenever you want to guarantee there is one and only one instance of an object in the system. For instance, you may want to make sure that you're always using the same instance of a database connection. Suppose you did it this way...

    PHP Code:
    class Db {
        function 
    main() {
            return new 
    MysqlConnection(
                new 
    DbConnectionInfo('host''db''user''pass'));
        }
    }

    Db::main()->beginTransaction();
    do_something();
    function 
    do_something() {
        
    Db::main()->query('something');
    }
    Db::main()->commit(); 
    This isn't only really ugly and unrealistic, but it won't work as expected since Db::main() returns a new connection upon every call.

    PHP Code:
    class Db {
        function 
    main() {
            static 
    $instance;
            if (
    null === $instance) {
                
    $instance = new MysqlConnection(
                    new 
    DbConnectionInfo('host''db''user''pass'));
            }
            return 
    $instance;
        }
    }

    Db::main()->beginTransaction();
    do_something();
    function 
    do_something() {
        
    Db::main()->query('something');
    }
    Db::main()->commit(); 
    This will work as expected, since Db::main() is now returning the same instance of the database connection.

    Now I have a question though. Suppose I have two databases on different hosts, and I want to talk to each using a MysqlConnection object. I tried to think of how to set this up using phemto and came to the conclusion that I'd have to do something like this...

    PHP Code:
    class DbOneConnection extends MysqlConnection {
        function 
    __construct() {
            
    parent::__construct(new DbConnectionInfo('host1''db1''user''pass'));
        }
    }

    class 
    DbTwoConnection extends MysqlConnection {
        function 
    __construct() {
            
    parent::__construct(new DbConnectionInfo('host2''db2''user''pass'));
        }
    }

    $phemto
        
    ->register(new Singleton('DbOneConnection'))
        ->
    register(new Singleton('DbTwoConnection'));

    $phemto->instantiate('DbOneConnection'); 
    That's fine I guess, but let's say I introduce another object into the mix...

    PHP Code:
    class UserGateway {
        function 
    __construct(MysqlConnection $db) {
            
    $this->db $db;
        }

    This is a problem obviously, because when phemto goes to fill in this dependency, it's going to find two candidates, although I most likely only want one. I can obviously change the type hint to use DbOneConnection, etc., but that just feels wrong. Too much coupling.

    Any way around this?

  13. #38
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    For that we'd need some kind of labelling, eg:

    PHP Code:
    // configuration stage
    $injector->register(..singleton conn..)->as('label_1');
    $injector->register(..singleton conn..)->as('label_2');
    $injector->register(..client of label_1..)->using('label_1');
    $injector->register(..client of label_2..)->using('label_2'); 
    Or if you wanted to specify the instance at instantiation:
    PHP Code:
    $injector->instantiate('Foo')->using('label_1');
    $injector->instantiate('Bar')->using('label_2'); 
    Or suppose phemto could divide itself into different regions of the object graph, with each subgraph inheriting settings from its parent and adding some additional configuration of its own:

    PHP Code:
    // config stage
    $main_graph = new Phemto;
    $subgraph_1 $main_graph->getSubGraph(); // a new instance of Phemto
    $subgraph_2 $main_graph->getSubGraph(); // a new instance of Phemto

    $main_graph->register('ThisConnectionClient');
    $main_graph->register('ThatConnectionClient');
    $subgraph_1->register(new Singleton('MysqlConnection', array('..params for host 1..')));
    $subgraph_2->register(new Singleton('MysqlConnection', array('..params for host 2..')));

    // client code
    $foo $subgraph_1->instantiate('ThisConnectionClient'); // gets conn to host 1
    $bar $subgraph_2->instantiate('ThatConnectionClient'); // gets conn to host 2 
    This might be simpler in that there is no messing around with labels: just pick the correct $subgraph. I haven't really thought that through though.

  14. #39
    SitePoint Addict
    Join Date
    Feb 2007
    Posts
    251
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Cool. That would be nice. Any plans to add that type of capability in there or should I begin to hack away?

  15. #40
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Which one do you like best?

    In general, I think anything which satisfies a real need should go in, with the simplest possible interface. That was straight off the top of my head and needs to be thrashed around a bit. Any other ideas?

  16. #41
    SitePoint Addict
    Join Date
    Feb 2007
    Posts
    251
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I like the subgraph approach myself. I like that it allows you to provide a default implementation in a simple way. It's also not as wordy as the label approach.

  17. #42
    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)
    The subgraph approach seems to me as the simplest solution. It's supported by other containers too.

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

    I am having trouble keeping up with the speed of this thread .

    I have been hacking away at some acceptance tests. See the acceptance_tests.php in the current SVN repo. These don't run yet as this is just a feature spec. A quick summary:

    New:

    1) Name changes. register() was too internal.
    2) Fulfilling dependencies based on variable name.
    3) Sessionable promoted to first class status.
    4) Setter injection.
    5) Nested injectors (chain of responsibilty style) for specific
    interface overrides.
    6) Direct support for decorators/filters.

    Removed:

    1) Direct passing of parameters. Did you use this? What are the use
    cases I need to address in it's absence?

    Todo:

    1) A way for users to create their own lifecycles.

    Looks like I guessed right with subgraphs (phew). What else do people need?

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

  19. #44
    SitePoint Addict
    Join Date
    Feb 2007
    Posts
    251
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I am having trouble keeping up with the speed of this thread .
    Can't tell from this side of the screen!

    Direct passing of parameters. Did you use this? What are the use
    cases I need to address in it's absence?
    I'm trying to figure out how I would implement the multiple database use case from above with the new code. I don't have any interfaces, just the following classes...

    PHP Code:
    class DbConnectionInfo {
        function 
    __construct($type$host$db$username$password) {
            
    $this->type $type;
            
    $this->host $host;
            
    $this->db $db;
            
    $this->username $username;
            
    $this->password $password;
        }
    }
    class 
    DbConnection {
        function 
    __construct(DbConnectionInfo $info) {
        }
    }
    class 
    SchemaInfoGateway {
        function 
    __construct(DbConnection $dbAlpha) {
            
    $this->db $dbAlpha;
        }
    }
    class 
    MysqlInfoGateway {
        function 
    __construct(DbConnection $dbOmega) {
            
    $this->db $dbOmega;
        }

    I obviously can't do this...

    PHP Code:
    $injector = new Phemto();
    $injector->forVariable('dbAlpha')->willUse(new Singleton('DbConnection',
        array(new 
    DbConnectionInfo('mysql''localhost''information_schema''root'''))));
    $injector->forVariable('dbOmega')->willUse(new Singleton('DbConnection',
        array(new 
    DbConnectionInfo('mysql''localhost''mysql''root''')))); 
    That won't work since the parameters are gone. I really like the idea of mapping the variable name this way though.

    Take this alternative approach...

    PHP Code:
    $injector
    ->whenCreating('SchemaInfoGateway')->willUse(new Singleton('AlphaDbConnection'))
    ->
    whenCreating('MysqlInfoGateway')->willUse(new Singleton('OmegaDbConnection')); 
    First, I don't really want to create distinct implementations if I can get away with passing in some configuration info via constructor parameters, but the bigger problem I see is related to the lifecycle of the instances.

    PHP Code:
    $injector
    ->whenCreating('SchemaInfoGateway')->willUse(new Singleton('AlphaDbConnection'))
    ->
    whenCreating('MysqlInfoGateway')->willUse(new Singleton('OmegaDbConnection'))
    ->
    whenCreating('AnotherGateway')->willUse(new Singleton('AlphaDbConnection')); 
    What's going to happen there? I assume SchemaInfoGateway and AnotherGateway will actually get different singletons? Maybe not? I see the potential for confusion due to this ambiguity, whereas the variable mapping is very transparent -- use this variable name anywhere, get this singleton.

    In any case, I'm still a little confused about how to implement the use case with the upcoming changes. Any chance you can shed some light?

    Also, I went looking in acceptance_tests.php for a sign of the subgraph approach mentioned above, but I came up empty. Is it hiding in there somewhere?

  20. #45
    SitePoint Evangelist tetsuo shima's Avatar
    Join Date
    Oct 2005
    Location
    Switzerland
    Posts
    597
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi,

    I'm happy to announce that I'm a phemto converted user.

    I think that once the creative process going on right now will slow down, it would be nice to have a more "in-depth" documentation.

    Congratz on the good job. Phemto is clear, easy to use and super light.
    The SEO Faq thread
    Dependency injection made easy: Phemto

  21. #46
    SitePoint Enthusiast
    Join Date
    Jun 2007
    Posts
    27
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Removed:

    1) Direct passing of parameters. Did you use this? What are the use
    cases I need to address in it's absence?
    Do you mean passing parameters at the registration ($injector->register(new Singleton("Foo", array("bar", "asd")))) or at the instantiation ($injector->instantiate("Foo", array("bar", "asd"))) ? While I used the first one quite often in my application I never used the second, although I can imagine some use cases for quick testing purposes

  22. #47
    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 don't remember if I mentioned this before, but I would prefer create over instantiate. I'm not completely sold on all the fluent-style method names either. For example, whenCreating and forVariable have very similar semantics, so I think they should be named similarly to reflect this.

    I don't know if I like the wrapper feature. It's quite a common use-case to wrap things up, but there is really no need for a special construct for this; You can just register the wrapper as the main implementation, and then register the wrapped specifically for the wrapper. Eg.:

    PHP Code:
    $injector = new Phemto();
    $injector->willUse('WrapperForBare');
    $injector->whenCreating('WrapperForBare')->willUse('BareImplementation'); 
    Maybe this is such a common thing to do, that it mandates a special functionality for it, but I'm sceptical about bloating the library.

    Quote Originally Posted by lastcraft View Post
    1) Direct passing of parameters. Did you use this? What are the use
    cases I need to address in it's absence?
    Agree - That doesn't belong in Phemto. I think there's a difference between wiring up objects and runtime creation of objects. Because PHP is such a dynamic language, the line between the two may be a bit blurry. But if you need to create objects in runtime, they will usually be very simple (And thus doesn't need a container) or you should write a factory for the purpose.

  23. #48
    ********* 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 cuberoot View Post
    I'm trying to figure out how I would implement the multiple database use case from above with the new code.
    There's no code as such, just some acceptance tests acting as a spec. The only code is the old version.

    Hm...tricky. What would you like the syntax to look like?

    Quote Originally Posted by cuberoot View Post
    I obviously can't do this...
    There are at least two possibilities:

    1) Singleton creates a new instance when given different parameters. This could be seriously accident prone. We could have the created instance passed to Phemto rather than have Phemto create it though. prhaps an Instance lifecycle. I might try to sketch out something speculative later on.

    2) Singleton has some notion of scope. Perhaps a Shared lifecycle rather than Singleton. I don't want to write this so much as supply the facilities to write it. I haven't a clue how to do this right now.

    I think I'll code the next alpha iteration and see where we go next. Nice use case though.

    Regarding the excessive fluency of willUse() after whenCreating(), I think some of it has to be reigned in. I think the frugality of this...
    PHP Code:
    $injector->willUse('Me')->willUse('You'); 
    ...is matched by...
    PHP Code:
    $injector->willUse('Me''You'); 
    I'm not sure I yet have those parameter spots free. The need to populate unassigned variables might still be with me.

    Quote Originally Posted by cuberoot View Post
    Also, I went looking in acceptance_tests.php for a sign of the subgraph approach mentioned above, but I came up empty. Is it hiding in there somewhere?
    See the CanUseDifferentDependencySetWithinAnInterface test case.

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

  24. #49
    ********* 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 View Post
    I don't remember if I mentioned this before, but I would prefer create over instantiate.
    So do I. Instantiate is technically more correct, but everyone says "create" in normal programmer speech. I've nearly changed it about a half dozen times. I'll definitely change it now.

    Quote Originally Posted by kyberfabrikken View Post
    I'm not completely sold on all the fluent-style method names either. For example, whenCreating and forVariable have very similar semantics, so I think they should be named similarly to reflect this.
    I don't know yet if they are the same. My gut feeling is that there is a difference in there. whenCreating() creates a nested scope, but forVariable() is using the original source for target labels. E.g...
    PHP Code:
    $injector->whenCreating('Stuff')->forVariable('thing')->willUse('MyThing'); 
    ...means that only when I instantiate a Stuff does the variable $thing get a MyThing instance. $thing elsewhere will be unaffected.

    Quote Originally Posted by kyberfabrikken View Post
    Maybe this is such a common thing to do, that it mandates a special functionality for it, but I'm sceptical about bloating the library.
    My thought went something like this. I use a framework that uses Phemto. It comes with a wiring file, and I have to append my wiring file to manipulate the framework. I want to add a Decorator to some part of it (I want to cache PermissionSet or something). How can I do this without knowing anything about the existing wiring file?

    This scenario pops into my head a lot. It's all a bit unclear and muddy to me right now. Perhaps fellow SitePointers can sharpen the use cases a little.

    Quote Originally Posted by kyberfabrikken View Post
    Agree - That doesn't belong in Phemto. I think there's a difference between wiring up objects and runtime creation of objects.
    That was my thinking, but a concrete use case could sink me pretty quick.

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

  25. #50
    ********* 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 myc View Post
    While I used the first one quite often in my application I never used the second, although I can imagine some use cases for quick testing purposes
    I'd love a concrete example of when you've done this. Please, please tell me more.

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


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
  •