ServiceManager, an object with __constructor parameters.

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

ServiceManager, an object with __constructor parameters.

Philip Gabbert
As pointed out earlier by our lord and savior Matthew O'Phinney, Zend\Di is
becoming less desired component in favor of ServiceManager.

Works for me. I agree SM is much easier to use, except in one instance. So
I turn to the community to help me resolve this one instance:

> How do I get a ServiceManager object with __constructor() parameters?

My dilemma: I'm building a super-small application with very limited
requirements that is dependent on PDO.

However, PDO requires constructor parameters. How do I create a PDO loader
that can 1) be cached by PHP5.5 opcode 2) doesn't require a bunch of other
classes and 3) can be loaded only at the time I need to make a PDO call.
(speed of application is #1 requirement)

$sm->get('PDO'); doesn't work since I can't pass in construction parameters.
$sm->get('Db'); won't work either, since construction parameters exist
within the same file the closure would be included:

```
app.config.php = [
  'sm' => array(
        "factories" => array(
            'Db' => function ($sm) {
                (PS: Are these cached now? I recall some caching issues
with embedded closures)
                // $sm->get('Config');  is invalid; not using
Zend\Application that would inject this.
                //return new PDO(); // No way to get construct parameters
below...
            },
        )
    ),
// ....
    "db" => [
        "dsn" =>
'cassandra:host=127.0.0.1;port=9160,host=127.0.0.2;port=9162;version=3.0.0;dbname=test',
        "username" => null,
        "password" => null,
    ],
];
```

For Di, I could pass in the parameters: $di->get('PDO', $cfg['db']);
This isn't possible for SM. This little functionality would make a world of
difference.

---
Philip
[hidden email]
http://www.gpcentre.net/
Reply | Threaded
Open this post in threaded view
|

Re: ServiceManager, an object with __constructor parameters.

franz de leon
i think the AbstractPluginManager had a seconds argument that is passed to
the constructor.
On Jan 10, 2014 7:57 PM, "Philip G" <[hidden email]> wrote:

> As pointed out earlier by our lord and savior Matthew O'Phinney, Zend\Di is
> becoming less desired component in favor of ServiceManager.
>
> Works for me. I agree SM is much easier to use, except in one instance. So
> I turn to the community to help me resolve this one instance:
>
> > How do I get a ServiceManager object with __constructor() parameters?
>
> My dilemma: I'm building a super-small application with very limited
> requirements that is dependent on PDO.
>
> However, PDO requires constructor parameters. How do I create a PDO loader
> that can 1) be cached by PHP5.5 opcode 2) doesn't require a bunch of other
> classes and 3) can be loaded only at the time I need to make a PDO call.
> (speed of application is #1 requirement)
>
> $sm->get('PDO'); doesn't work since I can't pass in construction
> parameters.
> $sm->get('Db'); won't work either, since construction parameters exist
> within the same file the closure would be included:
>
> ```
> app.config.php = [
>   'sm' => array(
>         "factories" => array(
>             'Db' => function ($sm) {
>                 (PS: Are these cached now? I recall some caching issues
> with embedded closures)
>                 // $sm->get('Config');  is invalid; not using
> Zend\Application that would inject this.
>                 //return new PDO(); // No way to get construct parameters
> below...
>             },
>         )
>     ),
> // ....
>     "db" => [
>         "dsn" =>
>
> 'cassandra:host=127.0.0.1;port=9160,host=127.0.0.2;port=9162;version=3.0.0;dbname=test',
>         "username" => null,
>         "password" => null,
>     ],
> ];
> ```
>
> For Di, I could pass in the parameters: $di->get('PDO', $cfg['db']);
> This isn't possible for SM. This little functionality would make a world of
> difference.
>
> ---
> Philip
> [hidden email]
> http://www.gpcentre.net/
>
Reply | Threaded
Open this post in threaded view
|

Re: ServiceManager, an object with __constructor parameters.

franz de leon
In reply to this post by Philip Gabbert
another trick ala functional programming is returning a closure insidebof a
closure:

array(
   'factories' => array(
        'db' => function ($sm) {
            return function ($constructorArgs) {
                return new Db($constructorArgs);
             };
        },
    )
)

you would then use this as

$db = $this->getServiceLocator()->get('db');
$db('someparam');

or

$db->__invoke('someparam');

since its a bit hacky. i am not sure how others would approve it.
On Jan 10, 2014 7:57 PM, "Philip G" <[hidden email]> wrote:

> As pointed out earlier by our lord and savior Matthew O'Phinney, Zend\Di is
> becoming less desired component in favor of ServiceManager.
>
> Works for me. I agree SM is much easier to use, except in one instance. So
> I turn to the community to help me resolve this one instance:
>
> > How do I get a ServiceManager object with __constructor() parameters?
>
> My dilemma: I'm building a super-small application with very limited
> requirements that is dependent on PDO.
>
> However, PDO requires constructor parameters. How do I create a PDO loader
> that can 1) be cached by PHP5.5 opcode 2) doesn't require a bunch of other
> classes and 3) can be loaded only at the time I need to make a PDO call.
> (speed of application is #1 requirement)
>
> $sm->get('PDO'); doesn't work since I can't pass in construction
> parameters.
> $sm->get('Db'); won't work either, since construction parameters exist
> within the same file the closure would be included:
>
> ```
> app.config.php = [
>   'sm' => array(
>         "factories" => array(
>             'Db' => function ($sm) {
>                 (PS: Are these cached now? I recall some caching issues
> with embedded closures)
>                 // $sm->get('Config');  is invalid; not using
> Zend\Application that would inject this.
>                 //return new PDO(); // No way to get construct parameters
> below...
>             },
>         )
>     ),
> // ....
>     "db" => [
>         "dsn" =>
>
> 'cassandra:host=127.0.0.1;port=9160,host=127.0.0.2;port=9162;version=3.0.0;dbname=test',
>         "username" => null,
>         "password" => null,
>     ],
> ];
> ```
>
> For Di, I could pass in the parameters: $di->get('PDO', $cfg['db']);
> This isn't possible for SM. This little functionality would make a world of
> difference.
>
> ---
> Philip
> [hidden email]
> http://www.gpcentre.net/
>
Reply | Threaded
Open this post in threaded view
|

Re: ServiceManager, an object with __constructor parameters.

Stefano Torresi
CONTENTS DELETED
The author has deleted this message.
Reply | Threaded
Open this post in threaded view
|

Re: ServiceManager, an object with __constructor parameters.

Philip Gabbert
On Mon, Jan 13, 2014 at 4:11 AM, Stefano Torresi
<[hidden email]>wrote:

> So there you go: https://gist.github.com/stefanotorresi/8399139
>
> You may want to get it further and use an AbstractOption subclass to
> enforce defaults and/or validate configs.
>

Oh. I see. I didn't think to use services that way. That works out well. I
can even set a "class" index that has the class name to use, which would
allow a simple method for DB Injections.

Let me ask this now: would it be worth while just to set the while
application config within a "Config" service? AbstractOption isn't
necessary: it's an inhouse script only. There will be no outside users
access and modifying the code. However, I do see that use in public code
base; internally we can pressure our developers do to things right. I
wanted DI for the purpose of unit testing.



> By the way, yes, anonymous functions inside configurations array are not
> cacheable, and so are object instances (i.e. using 'new Obj()' as an array
> value).
>
>
I was afraid of this. Albeit this might not be a bottle neck, speed is a
concern of ours. We'll see if this has any micro-optimization speed
implications in the end. Thanks!

---
Philip
[hidden email]
http://www.gpcentre.net/
Reply | Threaded
Open this post in threaded view
|

Re: ServiceManager, an object with __constructor parameters.

weierophinney
Administrator
On Mon, Jan 13, 2014 at 12:06 PM, Philip G <[hidden email]> wrote:

> On Mon, Jan 13, 2014 at 4:11 AM, Stefano Torresi
> <[hidden email]>wrote:
>
>> So there you go: https://gist.github.com/stefanotorresi/8399139
>>
>> You may want to get it further and use an AbstractOption subclass to
>> enforce defaults and/or validate configs.
>>
>
> Oh. I see. I didn't think to use services that way. That works out well. I
> can even set a "class" index that has the class name to use, which would
> allow a simple method for DB Injections.
>
> Let me ask this now: would it be worth while just to set the while
> application config within a "Config" service? AbstractOption isn't
> necessary: it's an inhouse script only. There will be no outside users
> access and modifying the code. However, I do see that use in public code
> base; internally we can pressure our developers do to things right. I
> wanted DI for the purpose of unit testing.
>
>
>
>> By the way, yes, anonymous functions inside configurations array are not
>> cacheable, and so are object instances (i.e. using 'new Obj()' as an array
>> value).
>>
>>
> I was afraid of this. Albeit this might not be a bottle neck, speed is a
> concern of ours. We'll see if this has any micro-optimization speed
> implications in the end. Thanks!

Actually, from a performance perspective, factory classes are a much
better fit. The reason is that the code from them is only retrieved
and compiled when requested. When you use closures, those must be
compiled on each request.

(Ask Marco Pivetta and Michael Gallego about this sometime - I was
surprised, as well!)


--
Matthew Weier O'Phinney
Project Lead            | [hidden email]
Zend Framework          | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc

--
List: [hidden email]
Info: http://framework.zend.com/archives
Unsubscribe: [hidden email]