ZF2 — Загрузка моделей в Service Manager

В моем файле конфигурации модуля эти строки загружают библиотеки и модели в 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;
},
),
),

1

Решение

Вы должны рассмотреть возможность использования AbstractFactory в этом случае. Смотрите код ниже:

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'
]
]
2

Другие решения

Вы также можете использовать инициализаторы:

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);
}

и реализует этот интерфейс в ваших модельных классах. Это зависит от Вас, как это сделать. На мой взгляд, лучший способ — создать абстрактный класс, а затем расширить его конкретным классом.

1

По вопросам рекламы [email protected]