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

Commit c0655c0

Browse files
committed
Adds the InvokableFactory
Most of the component refactors are complete, and will need to be re-done. However, one item that should likely be retained is usage of the `InvokableFactory` for invokable instances. This patch adds that factory to the v2 series, having it implement `Zend\ServiceManager\FactoryInterface`, but retaining the defined invokable method from v3. It raises an exception if the `$requestedName` is not provided, ensuring that any tests against the functionality are using a `ServiceManager` instance.
1 parent 3fd0ca3 commit c0655c0

File tree

3 files changed

+133
-0
lines changed

3 files changed

+133
-0
lines changed

src/Factory/InvokableFactory.php

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
/**
3+
* Zend Framework (http://framework.zend.com/)
4+
*
5+
* @link http://github.com/zendframework/zf2 for the canonical source repository
6+
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
7+
* @license http://framework.zend.com/license/new-bsd New BSD License
8+
*/
9+
10+
namespace Zend\ServiceManager\Factory;
11+
12+
use Interop\Container\ContainerInterface;
13+
use Zend\ServiceManager\Exception\InvalidServiceNameException;
14+
use Zend\ServiceManager\FactoryInterface;
15+
use Zend\ServiceManager\ServiceLocatorInterface;
16+
17+
/**
18+
* Factory for instantiating classes with no dependencies or which accept a single array.
19+
*
20+
* The InvokableFactory can be used for any class that:
21+
*
22+
* - has no constructor arguments;
23+
* - accepts a single array of arguments via the constructor.
24+
*
25+
* It replaces the "invokables" and "invokable class" functionality of the v2
26+
* service manager, and can also be used in v2 code for forwards compatibility
27+
* with v3.
28+
*/
29+
final class InvokableFactory implements FactoryInterface
30+
{
31+
/**
32+
* Create an instance of the requested class name.
33+
*
34+
* @param ContainerInterface $container
35+
* @param string $requestedName
36+
* @param null|array $options
37+
* @return object
38+
*/
39+
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
40+
{
41+
return (null === $options) ? new $requestedName : new $requestedName($options);
42+
}
43+
44+
/**
45+
* Create an instance of the named service.
46+
*
47+
* If `$requestedName` is not provided, raises an exception; otherwise,
48+
* proxies to the `__invoke()` method to create an instance of the
49+
* requested class.
50+
*
51+
* @param ServiceLocatorInterface $serviceLocator
52+
* @param null|string $canonicalName Ignored
53+
* @param null|string $requestedName
54+
* @return object
55+
* @throws InvalidServiceNameException
56+
*/
57+
public function createService(ServiceLocatorInterface $serviceLocator, $canonicalName = null, $requestedName = null)
58+
{
59+
if (! $requestedName) {
60+
throw new InvalidServiceNameException(sprintf(
61+
'%s requires that the requested name is provided on invocation; please update your tests or consuming container',
62+
__CLASS__
63+
));
64+
}
65+
return $this($serviceLocator, $requestedName);
66+
}
67+
}

test/Factory/InvokableFactoryTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
/**
3+
* Zend Framework (http://framework.zend.com/)
4+
*
5+
* @link http://github.com/zendframework/zf2 for the canonical source repository
6+
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
7+
* @license http://framework.zend.com/license/new-bsd New BSD License
8+
*/
9+
10+
namespace ZendTest\ServiceManager\Factory;
11+
12+
use Interop\Container\ContainerInterface;
13+
use PHPUnit_Framework_TestCase as TestCase;
14+
use Zend\ServiceManager\Factory\InvokableFactory;
15+
use ZendTest\ServiceManager\TestAsset\InvokableObject;
16+
17+
/**
18+
* @covers \Zend\ServiceManager\Factory\InvokableFactory
19+
*/
20+
class InvokableFactoryTest extends TestCase
21+
{
22+
public function testCanCreateObject()
23+
{
24+
$container = $this->getMock(ContainerInterface::class);
25+
$factory = new InvokableFactory();
26+
27+
$object = $factory($container, InvokableObject::class, ['foo' => 'bar']);
28+
29+
$this->assertInstanceOf(InvokableObject::class, $object);
30+
$this->assertEquals(['foo' => 'bar'], $object->options);
31+
}
32+
}

test/TestAsset/InvokableObject.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
/**
3+
* Zend Framework (http://framework.zend.com/)
4+
*
5+
* @link http://github.com/zendframework/zf2 for the canonical source repository
6+
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
7+
* @license http://framework.zend.com/license/new-bsd New BSD License
8+
*/
9+
10+
namespace ZendTest\ServiceManager\TestAsset;
11+
12+
class InvokableObject
13+
{
14+
/**
15+
* @var array
16+
*/
17+
public $options;
18+
19+
/**
20+
* @param array $options
21+
*/
22+
public function __construct(array $options = [])
23+
{
24+
$this->options = $options;
25+
}
26+
27+
/**
28+
* @return array
29+
*/
30+
public function getOptions()
31+
{
32+
return $this->options;
33+
}
34+
}

0 commit comments

Comments
 (0)