0

私のアプリケーションは POPO のコレクションであり、Zend Framework 2 Service Manager を使用してこれらの 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依存しています。と の両方に定義されたサービス名を使用して、Service Manager 構成を使用してこれらのサービスを挿入するにはどうすればよいですか?ServiceAServiceBmy.app.manager.taskServiceAServiceB

アップデート:

私は、自分の目的のために ServiceManager コンポーネントを使用するべきではなく、代わりに Zend DI コンポーネントを使用するべきだと考え始めています。

ServiceManager は ZF2 の「フレームワーク」コンポーネントであるという印象を受けますが、Zend\DI はより一般的な汎用 DiC のようです。したがって、これが ServiceManager と MVC および ModuleManager コンポーネント (「フレームワーク」コンポーネントのようにも見える) との結びつきの関係の理由である可能性があります。

多分誰かが明確にすることができますか?

4

3 に答える 3

2

module.config.php で Service Manager は 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() メソッドに入れます ZF2 の New Controller::init() :: phly, boy, phly

于 2014-03-15T06:02:01.883 に答える
0

私にとって最良の方法は、クラス ファクトリを作成し、次のように 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;
    }
}

Task クラスにファクトリ インターフェイスを実装できます。私は自分が構築しているものを制御することを好みます。

于 2014-03-15T16:09:18.810 に答える