下面是我注入任意类的初始化程序代码。一开始很难掌握——要在实例化时自动注入控制器,你必须在 module.config.php 的“controllers”部分的“initializer”部分定义初始化程序——而不是在“service_manager”部分。基本上是为了创建对控制器和其余部分有效的通用“感知接口”——各自的初始化密钥对应该完全出现在这两个部分中......
// module/SkeletonClassmapGenerator/Item/ImplementedItem/ImplementedItemInitializer.php
namespace SkeletonClassmapGenerator\Item\ImplementedItem;
use Zend\ServiceManager\InitializerInterface;
use SkeletonClassmapGenerator\Provider\GenericInitializerTrait;
class ImplementedItemInitializer implements InitializerInterface
{
static protected $T_NAMESPACE = __NAMESPACE__;
static protected $T_CLASS = __CLASS__;
use GenericInitializerTrait;
}
然后对于特征(显然在所有初始化程序之间共享)......
// module/SkeletonClassmapGenerator/Provider/GenericInitializerTrait.php
namespace SkeletonClassmapGenerator\Provider;
use Zend\ServiceManager\ServiceLocatorInterface;
trait GenericInitializerTrait
{
public function initialize($instance, ServiceLocatorInterface $serviceLocator)
{
if (isset(static::$T_CLASS)&&(isset(static::$T_NAMESPACE))){
$classname = explode('\\', static::$T_CLASS);
$class = end($classname);
preg_match('/([\w]*)Initializer$/i', $class,$matches);
$basename = $matches[1];
if(is_subclass_of($instance,static::$T_NAMESPACE.'\\'.$basename.'AwareInterface')) {
$sl = (method_exists($serviceLocator,'getServiceLocator'))?
$serviceLocator->getServiceLocator():$serviceLocator;
$dependency = $sl->get(static::$T_NAMESPACE.'\\'.$basename.'Interface'); // I use 'Interface' as postfix for Service Manager invokable names
$instance->{'set'.$basename}($dependency);
}
}
}
}