Dependency injection Zend Framework 2服务管理器依赖项注入

Dependency injection Zend Framework 2服务管理器依赖项注入,dependency-injection,zend-framework2,servicemanager,Dependency Injection,Zend Framework2,Servicemanager,我的应用程序是POPO的集合,我正在尝试使用Zend Framework 2服务管理器将这些POPO连接起来 为了说明我的问题,请以以下示例为例: $config = array( 'services' => array( 'my.app.serviceA' => new \My\App\Services\ServiceA(), 'my.app.serviceB' => new \My\App\Services\ServiceB(),

我的应用程序是POPO的集合,我正在尝试使用Zend Framework 2服务管理器将这些POPO连接起来

为了说明我的问题,请以以下示例为例:

$config = array(
   'services' => array(
      'my.app.serviceA' => new \My\App\Services\ServiceA(),
      'my.app.serviceB' => new \My\App\Services\ServiceB(),

      'my.app.manager.task' => new \My\App\Manager\TaskManager(),
   ),

);
我的TaskManager类如下所示:

class TaskManager {

   protected $serviceA;
   protected $serviceB;

   public function setServiceA( \My\App\Service\ServiceA $serviceA )
   {
      $this->serviceA = $serviceA;
   }

   public function setServiceB( \My\App\Service\ServiceB $serviceB )
   {
      $this->serviceB = $serviceB;
   }

}
如您所见,
TaskManager
类同时依赖于
ServiceA
ServiceB
。如何使用为
ServiceA
ServiceB
定义的服务名称,使用服务管理器配置将这些服务注入
my.app.manager.task

更新:

我开始相信,我不应该为了自己的目的而使用ServiceManager组件,而是应该使用Zend DI组件

我的印象是ServiceManager是一个ZF2“框架”组件,而Zend\DI似乎更像是一个通用的通用DiC。因此,这可能是ServiceManager与MVC和ModuleManager组件(也似乎是“框架”组件)的捆绑关系的原因


也许有人可以澄清一下?

在module.config.php中,可以用7种不同的方式配置服务管理器:

return array(

    // instantiate the class for you when needed
    'invokables' => array(
        'commentController' => '\Comment\Controller\CommentController';
    ),

    // Aliasing a name to a known service name
    'aliases' => array(
        'Comment\Service' => 'commentService';
    ),

    // configure the instance of the object
    'factories' => array(
        'commentController' => function ($sm) {
            $locator = $sm->getServiceLocator();
            $controller = $locator->get('commentController');
            $controller->setCommentService($locator->get('Comment\Service'));
            return $controller;
        }
    ),

    // register already instantiated objects
    'services' => array(
        'commentController' => new \Comment\Controller\CommentController(),
    ),

    //factory instance that can create multiple services based on the name supplied to the factory.
    'abstract_factories' => array(
        'SomeModule\Service\FallbackFactory',
    ),

    // initialize the service whenever service created
    'initializers' => array(
        function ($instance, $sm) {
            if ($instance instanceof \Comment\Controller\CommentController){
                $instance->setCommentService($sm->get('Comment\Service'));
            }
        }
    ),

    // indicating whether or not a service should be shared
    'shared' => array(
        'commentController' => false,
    ),
);
在Module.php中

public function getControllerConfig() {
    return array(
        'factories' => array(
            'commentController' => function ($sm) {
                $controller = new \Comment\Controller\CommentController();
                $locator = $sm->getServiceLocator();
                $controller->setCommentForm($locator->get('commentForm'));
                $controller->setCommentService($locator->get('commentService'));
                return $controller;
            }
        )
    );
}
在控制器中使用简单:

 $commentService = $this->serviceLocator->get('Comment\Service');
将其放入getter或init()方法中 控制器中的

$yourService = $this->getServiceLocator()->get('your_service_alias');
在视图帮助程序中: 您应该通过viewHelper的构造函数从Module.php发送

    public function getViewHelperConfig() {
        return array(
            'factories' => array(
                'loginHelper' => function($sm) {
                    return new LoginHelper($sm);
                }
        )
   }
仓促

use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
    public class UseCaseBO implements ServiceLocatorAwareInterface {
      protected $serviceLocator;

      public function setServiceLocator(ServiceLocatorInterface $serviceLocator) {
        $this->serviceLocator = $serviceLocator;
      }

      public function getServiceLocator() {
        return $this->serviceLocator;
      }

      // now instance of Service Locator is ready to use
      public function someMethod() {
        $table = $this->serviceLocator->get('your_service_alias');
        //...
      }
    }

对我来说,最好的方法是创建类工厂并使用factoryInterface,如下所示:

 return array(

    'service_manager' => array(
        'factories' => [
            'Task' => 'Application\TaskFactory',
        ],
        'invokables' => array(
            'Task'=> 'Application\Task',
            'ServiceA'=> 'Application\ServiceA',
            'ServiceB' => 'Application\ServiceB'
        )
    ),
);
和工厂级:

class TaskFactory implements FactoryInterface {

    /** @var  ServiceLocatorInterface $serviceLocator */
    var $serviceLocator;

    public function createService(ServiceLocatorInterface $serviceLocator) {
        $sl = $this->serviceLocator = $serviceLocator;

        // you can get your registered services
        $serviceA = $sl->get('ServiceA');
        $serviceB = $sl->get('ServiceB');


        // You can build your class using the class loader
        $task = new Application\Task();

        // Or the Service Locator Again
        $task = $sl->get('Task');

        return $task;
    }
}

您可以在任务类上实现factory接口。我更喜欢控制我正在构建的内容。

我理解这一点,工厂不是解决方案(在我看来)。问题是,;如何设置配置,以便能够描述一个服务,然后将该服务注入另一个服务。你喜欢Spring框架bean连接是如何工作的吗?在zend中,我看不到链接bean-appcontext.xml的东西,但可能存在,但在每个有serviceLocator的地方,你都可以访问你的服务。如果你想为每个用例定义不同的文件,你可以在同一个地方定义用例的所有bean。您可以在factory include DIR中加载文件/config/usecase appcontext.php'但php不是J2EE.Amin。我感谢你的意见,但这是行不通的。Springbean引用只是我所追求的“技术”的一个例子。我想定义一个服务,然后将该服务定义注入另一个服务。我想您可以使用它:。但在任何你们访问servicelocator的地方,你们都可以访问你们注册的服务,关键是你们可以在任何地方访问servicelocator.Amin。再次感谢您的意见,但您似乎不理解这个问题。请停止发布答案。对不起。问题根本不是关于工厂,而是关于配置服务管理器以允许它将一个服务定义注入另一个服务定义。