Php ZF2-在Service Manager中加载模型

Php ZF2-在Service Manager中加载模型,php,zend-framework2,servicemanager,Php,Zend Framework2,Servicemanager,在我的模块配置文件中,我有这些行将库和模型加载到ServiceManager中,以便我可以在控制器中检索它们。您可以看到我的所有模型都需要相同的依赖关系。请问,如果没有这些重复的代码块,我如何注入它们?这在我看来是错误的,但我不知道如何为不同的库运行相同的代码行。还是我应该使用工厂?谢谢大家! 'service_manager' => array( 'abstract_factories' => array( 'Zend\Cache\Service\Stora

在我的模块配置文件中,我有这些行将库和模型加载到ServiceManager中,以便我可以在控制器中检索它们。您可以看到我的所有模型都需要相同的依赖关系。请问,如果没有这些重复的代码块,我如何注入它们?这在我看来是错误的,但我不知道如何为不同的库运行相同的代码行。还是我应该使用工厂?谢谢大家!

'service_manager' => array(
    'abstract_factories' => array(
        'Zend\Cache\Service\StorageCacheAbstractServiceFactory',
        'Zend\Log\LoggerAbstractServiceFactory',
    ),
    'aliases' => array(
        'translator' => 'MvcTranslator',
    ),
    'factories' => array(
        // Models
        'Application\Model\Photo' => function($serviceLocator) {
            $coreLibrary = $serviceLocator->get('Project\CoreLibrary');
            $io = $serviceLocator->get('Project\IO');
            $class = new Application\Model\Photo($coreLibrary, $io);
            return $class;
        },
        'Application\Model\Album' => function($serviceLocator) {
            $coreLibrary = $serviceLocator->get('Project\CoreLibrary');
            $io = $serviceLocator->get('Project\IO');
            $class = new Application\Model\Album($coreLibrary, $io);
            return $class;
        },
        'Application\Model\Tag' => function($serviceLocator) {
            $coreLibrary = $serviceLocator->get('Project\CoreLibrary');
            $io = $serviceLocator->get('Project\IO');
            $class = new Application\Model\Tag($coreLibrary, $io);
            return $class;
        },
        'Application\Model\User' => function($serviceLocator) {
            $coreLibrary = $serviceLocator->get('Project\CoreLibrary');
            $io = $serviceLocator->get('Project\IO');
            $class = new Application\Model\User($coreLibrary, $io);
            return $class;
        },
        'Application\Model\Message' => function($serviceLocator) {
            $coreLibrary = $serviceLocator->get('Project\CoreLibrary');
            $io = $serviceLocator->get('Project\IO');
            $class = new Application\Model\Message($coreLibrary, $io);
            return $class;
        },
    ),
),

在这种情况下,你应该考虑使用抽象工厂。请参阅下面的代码:

namespace Application\Model;
use Zend\ServiceManager\AbstractFactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

class AbstractModelFactory implements AbstractFactoryInterface
{
    public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName)
    {
        $requestedName = explode('\\', $requestedName);

        if ((!isset($requestedName[0]) || $requestedName[0] != 'Application')
            || (!isset($requestedName[1]) || $requestedName[1] != 'Model'))
        {
            return false;
        }

        $modelName = $requestedName[2];
        return class_exists('Application\Model\\'.$modelName);
    }

    public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName)
    {
        $requestedName = explode('\\', $requestedName);
        $modelName = $requestedName[2];

        $coreLibrary = $serviceLocator->get('Project\CoreLibrary');
        $io = $serviceLocator->get('Project\IO');
        $class = 'Application\Model\\'.$modelName;
        return new $class($coreLibrary, $io);
    }
}
然后像这样注册您的工厂:

'service_manager' => [
    'abstract_factories' => [
        'Application\Model\AbstractModelFactory'
    ]
]

您也可以使用初始值设定项:

public function getServiceConfig(){
    return array(
        'initializers' => array(
            function ($instance, $sm) {
                if($instance instanceof Model\CoreAndIOAwareInterface){
                    $coreLibrary = $serviceLocator->get('Project\CoreLibrary');
                    $io = $serviceLocator->get('Project\IO');
                    $instance->setCoreLibrary($coreLibrary);
                    $instance->setIO($io);
                }
            },
        )
    );
}
因此,您还应该创建接口:

interface CoreAndIOAwareInterface
{
    public function setCoreLibrary(CoreLibrary $coreLibrary);
    public function setIO(IO $io);
}
并在模型类中实现此接口。这取决于你怎么做。在我看来,最好的方法是创建抽象类,然后用具体类对其进行扩展