问题
If I wanted to use the same factory for any class that extended my base class, would I want to turn the base class factory into a named function, or is there a better way to do this?
$serviceManager => array(
'factories' => array(
'someBaseClass' => function($thisServiceManager) {
$db = $thisServiceManager->get('db');
$thisBaseClass = new \myNamespace\thisBaseClass($db);
return $thisBaseClass;
},
),
);
EDIT
Further to the answer I accepted, here's the code I've tested that works.
Class File
use Zend\ServiceManager\AbstractFactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class baseClassFactory implements \Zend\ServiceManager\AbstractFactoryInterface
{
public function canCreateServiceWithName (ServiceLocatorInterface $locator, $name, $requestedName = '')
{
return ('baseClass' === $name || is_subclass_of($name, 'baseClass'));
}
public function createServiceWithName (ServiceLocatorInterface $locator, $name, $requestedName = '')
{
$db = $locator->get('db');
$query = new $name($db);
return $query;
}
}
Configuration
$serviceManager => array(
'abstract_factories' => array(
'baseClassFactory',
),
);
回答1:
If I'm following your question, you have a bunch of classes that extend someBaseClass
, and you want them all to be manufactured in the same way?
If so, then that sounds like a good opportunity to use the abstract_factories
component in the ServiceManager
. The pseudo-code would be like:
// warning: untested pseudo-code
class MyAbstractFactory implements \Zend\ServiceManager\AbstractFactoryInterface {
public function canCreateServiceWithName($_, $_, $name) {
// if I'm asked for someBaseClass or a child of someBaseClass, return true: false otherwise
return ('someBaseClass' === $name || is_subclass_of($name, 'someBaseClass'));
}
public function createServiceWithName($locator, $_, $name) {
// your factory logic here
// $object = ...
return $object;
}
}
And your config would look like:
$serviceManager = [ 'abstract_factories' => [ 'MyAbstractFactory' ] ];
Using the concrete factories
, you'd have to repeat the same function for each extended class (AFAIK), which would be a pain to maintain (IMO). The abstract factory pattern above basically says: give me a class, I'll reflect it to see if it's the base class I care about and, if so, I'll run my factory to get it.
More info on abstract_factories if you've never used it before.
来源:https://stackoverflow.com/questions/24982221/zf2-autoloader-use-factory-for-base-class-on-extended-classes-as-well