2012-12-27 35 views
3

我有两个例子,我想使用服务管理器来获得服务,并通过配置来解决依赖关系,除了一个依赖/参数是可变的(伪代码因为我知道“得到”只允许一个参数):ZF2从服务管理器获得服务,附加参数

在控制器

,以获得从数据库的实体:

$sm = $this->getServiceLocator(); 
$myObject = $sm->get('Model', $id); 

在映射器(服务管理器应该得到相应的适配器):

$sm = $this->getServiceLocator(); 
$tableGateway = $sm->get('TableGateway', $table); 

实现此目标的最佳实践是什么?

回答

1

据我所知,这不是直接可能的,但是我在某处读到intializer是为了这种类型的场景。初始化器可以是任何实现InitializerInterface的类,它有一个方法initialize(),用对象(Model的Ex.instance)和服务管理器实例调用initialize()方法,您需要为你的每个对象都需要被初始化。建立初始化类后,你需要在服务管理器配置(module.config.php)或getServiceConfig()方法

虽然不能完全覆盖你的问题,但可能会有所帮助在正确的方向前进条目

编辑

什么是最好的做法来实现这一目标?

要回答这个

如果你的对象没有依赖性,你可以achevie这是

$myObject = new Model(); 
$myObject->find($id); which would initialize the model 

,如果你的模型具有依赖性,也如果你需要与其他一些物体后面的阶段替代型号您可以使用servicelocator的服务工厂配置来隔离对象创建过程,从而在Module.php中定义getServicConfig()方法中的服务(您也可以定义自己的工厂代码并在配置中引用它,但在大多数情况下用例简单的工厂定义就足够了)

public function getServiceConfig(){ 
    return array(
     'factories' => array(
      'Model' => function(ServiceLocatorInterface $sm) { 
       return new Model($dependency1, $dependency2...); 
      }, 
     ), 
    ); 
} 

然后模型接入代码将

$myObject = $this->serviceLocator()->get('Model'); 
$myObject->find($id); which would initialize the model 

最好的做法是定义需要被调用,实现了该接口的接口,其中包括发现($ ID)和所有其他方法Model类,通过这种方式,您可以使用实现该接口的任何其他对象替换您的工厂代码,并且不需要触摸Model对象的使用代码。

对于用例二,我假设您尝试重用或减少代码重复。如果你有有限的一套组合,你可以像下面

$tableGateway = $this->serviceLocator()->get('Model/table1'); 

注意这样定义

public function getServiceConfig(){ 
    return array(
     'factories' => array(
      'Model/table1' => function(ServiceLocatorInterface $sm) { 
       return new TableGateway('table1', $sm->get('db')); 
      }, 
      'Model/table2' => function(ServiceLocatorInterface $sm) { 
       return new TableGateway('table2', $sm->get('db')); 
      }, 
     . 
     . 
     . 
     . 
     ), 
    ); 
}  

访问表服务工厂实现它:“型号/表1”是命名空间并避免配置的覆盖,内部“/”将通过服务经理被删除,名称将被换成小写,在登记和获取。

在Zend \的ServiceManager \的ServiceManager店它所谓的保护特性canonicalNames。这是映射到cannonical名称,这是用汽提和由小写斜线的命名空间的命名空间的阵列。

+0

我了解的初始化器是用于连接其他服务的实例,而不是一个变量。 – tihe

1

什么你所描述的是不是真的了的ServiceManager是专为用例。就像它在锡说,这是管理服务的系统。使用它来获取单个实体并不合适。相反,使用的ServiceManager抢资源库,并使用该资料库抢实体:

$entity = $this->getServiceLocator()->get('FooRepository')->find($id); 

在你的第二个例子,好像你已经有了某种厂创建TableGateways。明智的做法是:

$gateway = $this->getServiceLocator()->get('TableGatewayFactory')->get($table); 

或者,你可以为每个网关定义个别服务:据

$gateway = $this->getServiceLocator()->get('FooTableGateway');