4

ベータ DI コードを ZF2 のリリース バージョンに変換しようとしています。現在、私は最初から落ち込んでおり、コントローラーに依存関係を持つことは正常ではないと思わせるコントローラーへの注入に関するドキュメントはないようです。

現在、いくつかのコードを実行しようとしているvar_dump('blah');exit;だけです...多くのことを試しましたが、今のところこれが機能することを期待しています:

module.config.php

'controllers' => array(
    'invokables' => array(
        'indexController' => 'Application\Controller\IndexController',
    )
)

Module.php

public function getControllerConfig() {
    return array(
        'factories' => array(
            'indexController'    => function(ControllerManager $cm) {
                var_dump('blah');exit;
            },
        ),
    );
}

今のところ何も起きておらず、かなりイライラしています...各コントローラーのファクトリーを作成することについて何か読んだことがありますが、33個あり、非常に狂っていて愚かだと思います...?

私が注入しようとしているのは、ユーザーを取得/保存するための userMapper のようなものです。したがって、registerAction は userMapper を使用してデータベースにユーザーを作成し、ログインしようとすると、userMapper を使用してそこにユーザーがいるかどうかを確認します。

4

3 に答える 3

2

ここでの問題は、'indexController' が呼び出し可能オブジェクトとファクトリの両方として定義されていることです。最初に呼び出し可能なものをチェックすると思うので、探しているものが見つかると、ファクトリでコードを実行しようとすることはありません。「invokables」配列のエントリを削除するだけです。

私はちょうどこの主題に関する記事を書きました。コントローラーごとに個別のファクトリー クラスを作成する代わりに、クロージャーを使用してそれを行うことができます。依存関係が呼び出し可能であるか、オプション配列で簡単に構成できる場合は、さらに簡単です。必要なのは、注入できるクラスをリストする配列だけです。http://zendblog.shinymayhem.com/2013/09/using-servicemanager-as-inversion-of.htmlをご覧ください。

于 2012-09-28T21:49:54.077 に答える
1

任意の Module.php でこのように簡単に実行できます

public function onBootstrap(\Zend\EventManager\EventInterface $e)
{
    $serviceManager = $e->getApplication()->getServiceManager();
    $myDependency = /*something*/;

    $controllerLoader = $serviceManager->get('ControllerLoader');
    $controllerLoader->addInitializer(function ($controller) use ($myDependency) {
        if (method_exists($instance, 'injectMyDependency')) {
            $controller->injectMyDependency($myDependency);
        }
    });
}

メソッドが存在するかどうかを確認するだけでなく、依存関係を必要とするコントローラーにインターフェイスを実装させ、コントローラーがそのインターフェイスのインスタンスであるかどうかを確認してから設定することを少しきれいにします...

于 2012-09-13T20:37:03.200 に答える
0

以下は、任意のクラスに挿入する私の Initializer コードです。把握するのは最初はややこしかったです-インスタンス化時にコントローラーに自動的に注入するには、module.config.phpの「コントローラー」セクションの「初期化子」セクションで初期化子を定義する必要があります-「service_manager」セクションではありません。基本的に、コントローラーと残りの部分に有効なユニバーサル「認識インターフェイス」を作成するには、それぞれの初期化キーペアが両方のセクションに表示される必要があります...

// module/SkeletonClassmapGenerator/Item/ImplementedItem/ImplementedItemInitializer.php

namespace SkeletonClassmapGenerator\Item\ImplementedItem;

use Zend\ServiceManager\InitializerInterface;
use SkeletonClassmapGenerator\Provider\GenericInitializerTrait;

class ImplementedItemInitializer implements InitializerInterface
{
    static protected $T_NAMESPACE = __NAMESPACE__;
    static protected $T_CLASS = __CLASS__;
    use GenericInitializerTrait; 
}

次に、特性(明らかにすべての初期化子間で共有されます)について...

// module/SkeletonClassmapGenerator/Provider/GenericInitializerTrait.php

namespace SkeletonClassmapGenerator\Provider;

use Zend\ServiceManager\ServiceLocatorInterface;

trait GenericInitializerTrait
{
    public function initialize($instance, ServiceLocatorInterface $serviceLocator)
    {       
       if (isset(static::$T_CLASS)&&(isset(static::$T_NAMESPACE))){
       $classname = explode('\\', static::$T_CLASS);        
       $class = end($classname);
       preg_match('/([\w]*)Initializer$/i', $class,$matches);
       $basename = $matches[1];
        if(is_subclass_of($instance,static::$T_NAMESPACE.'\\'.$basename.'AwareInterface')) {
            $sl = (method_exists($serviceLocator,'getServiceLocator'))?
            $serviceLocator->getServiceLocator():$serviceLocator;
             $dependency  = $sl->get(static::$T_NAMESPACE.'\\'.$basename.'Interface');  // I use 'Interface' as postfix for Service Manager invokable names           
             $instance->{'set'.$basename}($dependency);
            }
       }
   }

}

于 2013-05-21T18:52:05.567 に答える