ZF2 使用附加参数从服务管理器获取服务 [英] ZF2 get service from service manager with additional parameter

查看:27
本文介绍了ZF2 使用附加参数从服务管理器获取服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个示例,我想使用服务管理器获取服务并让它通过配置解析依赖项,除了一个可变的依赖项/参数(伪代码,因为我意识到get"只允许一个论点):

I have two examples where I would like to use the service manager to get a service and have it resolve the dependencies through configs, apart from one dependency/parameter which is variable (pseudo code because I realise 'get' only allows one argument):

在控制器中,从数据库中获取实体:

in controller, to get an entity from a database:

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

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

in mapper (the service manager should get the corresponding adapter):

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

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

What would be best practice to achieve this?

推荐答案

据我所知,这不是直接可行的,但我在某处读到过,初始化器适用于这种类型的场景.

To my knowledge this is not directly possible, but I read somewhere that intializer are meant for this type of scenario.

initializer 可以是任何实现 InitializerInterface 的类,它有一个方法 initialize(), initialize() 方法是用对象(Model 的实例)和服务管理器实例调用的,你需要为每一个写条件需要初始化的对象.构建初始化类后,您需要在服务管理器配置(module.config.php) 或 getServiceConfig() 方法中包含条目

initializer can be any class which implement InitializerInterface, which has a method initialize(), the initialize() method is called with the object (Ex.instance of Model) and the service manager instance, you need to write condition for each of your object that need to be initialized. after building the initializer class you need to include entries in the service manager configuration(module.config.php) or getServiceConfig() method

虽然没有完全涵盖您的问题,但可能有助于朝着正确的方向前进

Though not fully cover your question but may be helpful to move in the right direction

编辑

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

What would be best practice to achieve this?

回答这个问题

如果您的对象没有依赖项,您可以将其作为

If your object has no dependencies you can achevie this as

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

如果您的模型有依赖关系,并且如果您需要在开发阶段后期用其他对象替换模型,您可以将对象创建过程与服务定位器的服务工厂配置隔离,以实现这一点,在 getServicConfig() 方法(您也可以定义自己的工厂代码并在配置中引用它,但在大多数用例中简单的工厂定义就足够了)

if your model has dependencies and also if you need to replace Model with some other object later in the stage of development you can isolate the object creation process with service factory configuration of the servicelocator, to achieve this define the service inside getServicConfig() method in Module.php (you can also define your own factory code and refer it in the configuration but in most use case simple factory definition suffice)

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

最好的做法是定义一个接口,其中包括 find($id) 和所有其他需要调用的方法并在 Model 类中实现这个接口,这样你就可以用任何其他实现的对象替换你的工厂代码界面,您无需触摸 Model 对象的使用代码.

the best practice would be define an interface which include find($id) and all other method that need to be called and implement this interface in the Model class, this way you can replace your factory code with any other object that implement the interface and you don't need to touch your usage code of the Model object.

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

For the use case two I assume you try to reuse or reduce repeat of code. If you have finite set of combination you can achieve it like below

像这样定义服务工厂

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'));
            },
        .
        .
        .
        .
        ),
    );
}    

访问 table1 为

access table1 as

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

注意:'Model/table1'是为了命名空间,避免覆盖配置,内部'/'会被服务管理器删除,并且名称将被小写,无论是注册还是获取.

Note: 'Model/table1' is to namespace and avoid overwrite of config, internally '/' will be removed by service manager, and the names will be made lowercase, on both registration and get.

Zend\ServiceManager\ServiceManager 将它称为 canonicalNames 的内容存储在受保护的属性中.这是一个映射到规范名称的命名空间数组,这些命名空间是将斜杠去掉并变成小写的命名空间.

The Zend\ServiceManager\ServiceManager stores what it calls canonicalNames in a protected property. This is an array of namespaces mapped to the cannonical names, which are the namespace with the slashes stripped and made lowercase.

这篇关于ZF2 使用附加参数从服务管理器获取服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆