最好的方法是从您的类中完全删除静态方法。ZF2 使通过名称获取服务变得非常容易,因此对于这样的用例,您实际上不需要静态方法。
首先,清理你的服务:
namespace MyApp\Service;
use Doctrine\Common\Persistence\ObjectRepository;
use DoctrineModule\Validator\ObjectExists;
class ApiService
{
// ...
protected $validator;
public function __construct(ObjectRepository $objectRepository)
{
$this->validator = new \DoctrineModule\Validator\ObjectExists(array(
'object_repository' => $objectRepository,
'fields' => array('email')
));
}
public function exists($apiKey)
{
return $this->validator->isValid($apiKey);
}
// ...
}
现在为它定义一个工厂:
namespace MyApp\ServiceFactory;
use MyApp\Service\ApiService;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class ApiServiceFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$entityManager = $serviceLocator->get('Doctrine\ORM\EntityManager');
$repository = $entityManager->getRepository('Application\Entity\User');
return new ApiService($repository);
}
}
然后将服务名称映射到工厂(通常在您的模块中):
namespace MyApp;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
class Module implements ConfigProviderInterface
{
public function getConfig()
{
return array(
'service_manager' => array(
'factories' => array(
'MyApp\Service\ApiService'
=> 'MyApp\ServiceFactory\ApiServiceFactory',
),
),
);
}
}
注意:您可能希望简单地使用闭包而不是定义单独的工厂类,但是当您不使用该服务时,拥有工厂类会给您带来小的性能提升。此外,在配置中使用闭包意味着您无法缓存合并的配置,因此请考虑使用此处建议的方法。
这是一个没有工厂类的例子(同样,考虑使用上面解释的方法):
namespace MyApp;
use Zend\ModuleManager\Feature\ServiceProviderInterface;
class Module implements ServiceProviderInterface
{
public function getServiceConfig()
{
return array(
'factories' => array(
'MyApp\Service\ApiService' => function ($sl) {
$entityManager = $serviceLocator->get('Doctrine\ORM\EntityManager');
$repository = $entityManager->getRepository('Application\Entity\User');
return new MyApp\Service\ApiService($repository);
},
),
);
}
}
现在您可以在控制器中使用该服务:
class MyController extends AbstractActionController
{
// ...
public function apiAction()
{
$apiService = $this->getServiceLocator()->get('MyApp\Service\ApiService');
if ( ! $apiService->isValid($this->params('api-key')) {
throw new InvalidApiKeyException($this->params('api-key'));
}
// ...
}
// ...
}
您也可以在拥有服务管理器的任何地方检索它:
$validator = $serviceLocator->get('MyApp\Service\ApiService');
作为附加建议,请考虑简化您的服务。由于isValid
已经是您的验证器的一个方法,您可以简单地返回验证器本身(为了简单起见,这里使用闭包方法):
namespace MyApp;
use Zend\ModuleManager\Feature\ServiceProviderInterface;
use DoctrineModule\Validator\ObjectExists;
class Module implements ServiceProviderInterface
{
public function getServiceConfig()
{
return array(
'factories' => array(
'MyApp\Validator\ApiKeyValidator' => function ($sl) {
$entityManager = $serviceLocator->get('Doctrine\ORM\EntityManager');
$repository = $entityManager->getRepository('Application\Entity\User');
new ObjectExists(array(
'object_repository' => $objectRepository,
'fields' => array('email')
));
},
),
);
}
}