3

サービスマネージャーを使用してサービスを取得し、構成を介して依存関係を解決したい2つの例があります。ただし、変数である1つの依存関係/パラメーターは別です(「get」は1つの引数しか許可しないため、疑似コード):

コントローラで、データベースからエンティティを取得するには:

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

マッパーで(サービスマネージャーは対応するアダプターを取得する必要があります):

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

これを達成するためのベストプラクティスは何ですか?

4

2 に答える 2

1

あなたが説明しているのは、実際にはServiceManagerが設計されたユースケースではありません。缶に書いてあるように、それはサービスを管理するためのシステムです。個々のエンティティを取得するためにそれを使用することは、実際には適切ではありません。代わりに、servicemanagerを使用してリポジトリを取得し、そのリポジトリを使用してエンティティを取得します。

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

2番目の例では、TableGatewaysを作成するある種のファクトリがあるようです。賢明なアプローチは次のとおりです。

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

または、ゲートウェイごとに個別のサービスを定義できます。

$gateway = $this->getServiceLocator()->get('FooTableGateway');
于 2012-12-28T23:05:12.817 に答える
1

私の知る限り、これは直接可能ではありませんが、初期化子がこのタイプのシナリオ向けであることをどこかで読みました。

初期化子は、メソッド initialize() を持つ InitializerInterface を実装する任意のクラスにすることができます。initialize() メソッドは、オブジェクト (モデルの例) とサービス マネージャー インスタンスで呼び出されます。オブジェクトごとに条件を記述する必要があります。初期化する必要があります。初期化クラスを構築した後、サービス マネージャーの構成 (module.config.php) または getServiceConfig() メソッドにエントリを含める必要があります。

あなたの質問を完全にカバーしているわけではありませんが、正しい方向に進むのに役立つかもしれません

編集

これを達成するためのベストプラクティスは何ですか?

これに答えるには

オブジェクトに依存関係がない場合は、これを次のように達成できます

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

モデルに依存関係があり、開発段階の後半でモデルを他のオブジェクトに置き換える必要がある場合は、オブジェクト作成プロセスを servicelocator のサービス ファクトリ構成で分離できます。これを実現するには、getServicConfig() メソッド内でサービスを定義します。 Module.php (独自のファクトリ コードを定義して構成で参照することもできますが、ほとんどの場合、単純なファクトリ定義で十分です)

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 オブジェクトの使用法コードに触れる必要はありません。

ユース ケース 2 では、コードの再利用または繰り返しの削減を試みると仮定します。組み合わせの有限セットがある場合は、以下のように達成できます

このようにサービスファクトリーを定義します

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 にアクセスします

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

注: 「Model/table1」は名前空間にあり、構成の上書きを回避します。内部的に「/」はサービス マネージャーによって削除され、名前は登録と取得の両方で小文字になります。

Zend\ServiceManager\ServiceManager は、呼び出したものcanonicalNamesを保護されたプロパティに格納します。これは正規名にマップされた名前空間の配列であり、スラッシュが取り除かれ、小文字になった名前空間です。

于 2012-12-27T15:36:07.963 に答える