在控制器中,我可以使用此代码调用服务
$this->getServiceLocator()->get('MyServiceName');
它非常酷。
我在zf2中创建了一个自定义库。(/ vender / API) 我需要访问使用静态方法加载的所有服务。(如果可能的话) 仅举例来说。 我创建了这个自定义类。(这个(自定义)类的想法是不同的,它必须是独立的)
class Test extends AbstractModel {
protected $identifier;
protected $fullName;
protected $someText;
public function getService(){
}
}
如何使用静态方法/或我班级内不知道的东西调用加载的服务? 感谢
答案 0 :(得分:4)
不要那样做!之前已经讨论过,你最终可以阅读discussion on the mailing list,它也有一些很好的例子。
假设您的类Test
由于某种原因需要访问服务定位器,正确的方法是使用服务定位器将其实例化为硬依赖:
use Zend\ServiceManager\ServiceLocatorInterface;
class Test extends AbstractModel
{
// ...
public function __construct(ServiceLocatorInterface $serviceLocator)
{
$this->serviceLocator = $serviceLocator;
}
public function doFoo()
{
return $this->serviceLocator->get('FooService')->foo();
}
// ...
}
这样,你可以用$test = new Test($serviceLocator);
实例化它,或者在工厂中定义它,让服务定位器本身为你提供一个实例:
namespace MyApp;
use Zend\ModuleManager\Feature\ServiceProviderInterface;
class Module implements ServiceProviderInterface
{
public function getServiceConfig()
{
return array(
'factories' => array(
'Test' => function ($serviceLocator) {
return new \Test($serviceLocator);
},
),
);
}
}
这基本上可以在您的应用程序中提供服务'Test'
。
无论如何,你刚刚创造的东西有两个很大的缺陷:
在使用服务地点时,您应该注意一些陷阱。由于其性质,这是service location本身的问题:
您特此尝试在模型/实体中使用服务(和服务定位器)。这种误解/误用可能来自于您习惯active-record pattern这一事实,其中许多逻辑是表示DB记录的对象的一部分,如ZF1中的Zend_Db
。由于ZF2中的服务很容易定义和使用,请在服务中移动这样的逻辑。您在上面描述的是一个更像是值对象或实体的类,不应该包含复杂的业务逻辑。
如果您感兴趣,我还在why you should use use IOC instead of service location上写了一篇博文(第二段描述了服务地点的陷阱)。