Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Jan 8, 2020. It is now read-only.

Delegate factories #4110

Closed
wants to merge 369 commits into from
Closed

Conversation

Ocramius
Copy link
Member

I've been working on this concept for some time, but this is basically a cleaned up version of #2995

Why do we need this?

The idea is to be able to build delegates of any existing service. This can be used to build "decorators" for service instantiation and for proxying.

Delegation

Imagine that you have a DbConnection and a LoggedDbConnection object. A LoggedDbConnection wraps around a "real" DbConnection instance like following, but provides additional API that sends queries to a logger:

$connection = new LoggedDbConnection(new DbConnection());

Currently, our problem is that such a wrapper requires us to completely re-define the factory that instantiates DbConnection. There's no way to re-use logic from such a factory. We have to rewrite it and be aware of its internal logic:

    'db' => function ($sl) {
        // rewrite all ze logic here
        return new LoggedDbConnection($dbConnection);
    },

Proxying

We can proxy any service (with the assumption that we know its class name or implemented interface) and make it "lazy", so that its dependencies don't get instantiated when we request them. This allows us to build lightweight containers, as explained in https://github.com/Ocramius/ProxyManager/blob/master/docs/lazy-loading-value-holder.md. Also, we don't have to worry about how the original service is instantiated, since the original factory is still existing.

Example

In the following example, I've simply replaced the original service (instance of stdClass) with a new one that contains the original service in property tab:

<?php

use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\DelegateFactoryInterface;

require_once __DIR__ . '/vendor/autoload.php';

class FooDelegateFactory implements DelegateFactoryInterface
{
    public function createDelegateWithName(
        ServiceLocatorInterface $serviceLocator,
        $name,
        $requestedName,
        $callback
    ) {
        $foo      = new \stdClass();
        $foo->tab = $callback(); // php5.4, heh

        return $foo;
    }
}

$serviceManager = new ServiceManager();
$serviceManager->setFactory('foo', function() {
    $foo = new \stdClass();
    $foo->bar = 'baz';

    return $foo;
});
$serviceManager->setService('foo-delegate-factory',new FooDelegateFactory());
$serviceManager->setDelegate('foo', 'foo-delegate-factory');

var_dump($serviceManager->get('foo')->tab->bar); // baz

Implementation flaws

  • Additional method call to doCreate, since I splitted create to allow this kind of behavior
  • doCreate is public, since I cannot use a closure and call ->bindTo($this) in PHP 5.3
  • It may not be clear at first, but the delegate factory is a service (which is a huge advantage, but is a bit different from what we're used to see)

Mike Willbanks and others added 30 commits February 28, 2013 13:39
configuration.

Change-Id: Ibd9309bf42c8992376849a1c5bbae05cd82e4c13
Change-Id: I568ec78485724be3ec68c0b754d9af95b3ea1b03
Change-Id: I071cf7b8e41d3f7f06f942650dc6f8a3d2215cba
method.

Change-Id: I4a3bb387e4f63c5aa70519923ad3680c8ae5e5b0
method.

Change-Id: Idf4802f8735a2333d927f5c6989e124c048e7854
Change-Id: I382bc52191f3202b47ecd7910a2ffb4108c7e78e
Change-Id: Ib47b1604675e5beef8945b57df9dfb28ddef3ffd
Change-Id: Ifb6241ff0d3799dbefdd9bd160e7f14c3ab68bf8
Change-Id: Ibd0e492df076b801cb91078753bfe40bf77f63c0
Change-Id: Ia85eab01106afa54e8156dadb9fece15d73e9ae8
Minor improvements in abstract factory methods.

Change-Id: Ic6d1de0efede8780ff6d50126b98b50dee5fa5fb
Change-Id: Ib79a1e12bf93f53f44765ac2add526c3ccecfa6f
Change-Id: I32e556441e7ba46367b1a1a7485ab00e0cdcd6df
Change-Id: I93522febd9f4c61286a2bce36bf3a1333a54e1ae
fix php docblock : boolean should be bool

Conflicts:
	library/Zend/Filter/File/RenameUpload.php
	library/Zend/Mvc/Controller/Plugin/FilePostRedirectGet.php
	library/Zend/Mvc/Controller/Plugin/FlashMessenger.php
	library/Zend/Mvc/Controller/Plugin/PostRedirectGet.php
	library/Zend/Mvc/Router/SimpleRouteStack.php
fix (bool) casting : add space and use (bool) instead of (boolean) to cast
@weierophinney
Copy link
Member

@Ocramius ping me when this is no longer a WIP. :)

@Ocramius
Copy link
Member Author

@weierophinney I don't think this is WIP. I'm only concerned about the overhead of the additional call. I think we should inline some code like hasAlias and canonicalizeName, which is a minor BC break.

@Ocramius
Copy link
Member Author

Closing. Noticed that it was PR-ed against master. Opened #4145 instead

@Ocramius Ocramius closed this Mar 29, 2013
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.