2

私の ZF2 アプリケーションでは、Zend\Di\Diすべてのクラス インスタンスを作成するために使用します。DI 定義はZend\Di\Definition\CompilerDefinition、APC を使用してスキャンおよびキャッシュされます。これにより、遅いリフレクションを使用して実行時にクラスをスキャンすることを回避できます。インスタンスの作成中に例外が発生した場合 (DI 定義が古いため)、コードが再スキャンされ、定義がキャッシュされ、インスタンスが再度作成されます。

これは、新しいクラスまたは変更されたコンストラクターに対してファクトリーメソッド/クロージャーを作成または変更する必要がないため、開発中に非常に便利です。私のコンストラクターは、追加のコンストラクター パラメーターを指定せずに依存性注入が確実に機能するように、特定の規則 (型ヒント付きの引数と単一の $params 配列のみ) に従います。

これまでのところ、これは適切に機能し、バグを回避し (古いファクトリ メソッドがない)、開発をスピードアップします。ただし、スキャンされた定義は現在、APC で 1.8MB (シリアル化された配列) であり、増加しています。リクエストごとにキャッシュからロードする必要があるため、短時間にリクエストが多すぎるとメモリが枯渇する恐れがあります。ただし、これをシミュレートするための負荷テストのセットアップはありません。

Zend\Di\Di を使用する代わりに、Zend\ServiceManager を使用してすべてのクラスにファクトリ クロージャを記述することをお勧めします。しかし、これは大変な作業であり、開発中はかなり面倒だと思います。

この状況で Zend\ServiceManager にリファクタリングすることをお勧めしますか?

4

2 に答える 2

2

この問題の解決に役立つ ZF2 モジュールを作成しました: https://github.com/aimfeld/ZendDiCompiler

ZendDiCompilerは、依存性注入のために自動生成されたファクトリ コードを使用する Zend Framework 2 モジュールです。Zend\ServiceManager ファクトリ クロージャを作成して手動で最新の状態に保つ必要がなくなるため、多くの作業を節約できます。

ZendDiCompilerは (Zend\Di を使用して) コードをスキャンし、ファクトリ メソッドを自動的に作成します。ファクトリ メソッドが古い場合、ZendDiCompiler はそれらをバックグラウンドで更新します。したがって、より迅速に開発し、時代遅れのファクトリ メソッドによるバグを回避し、本番環境で優れたパフォーマンスを体験できます。

于 2013-03-08T09:58:37.107 に答える
1

これはまさに、私がZend\DiRADに関するブログ投稿で公開したものです。

開発にZend\Diは適していますが、本番環境ではメモリとパフォーマンスの大きなボトルネックになります。定義をキャッシュしても、インスタンスを操作するために引き続き使用ReflectionClassされます。call_user_func_array()また、注入パラメーターを調整するために必要な多くの周辺操作を実行する必要がありarray_mergeますZend\Di

Zend\Di\Diインスタンス マネージャをクロージャにコンパイルするためのモジュールを作成しました: OcraDiCompiler。少しクリーンアップする必要がありますが、その仕事は、Zend\Di内部のインスタンス化ロジックをトレースしてコード ファクトリ/クロージャを生成することです。それを少し「復活」させたい場合は、喜んでお手伝いします。なぜなら、それは私の TODO リストにありますが、今は優先度が低いからです。

とにかく、インスタンス化ロジックをファクトリー/クロージャーに移動するServiceManagerことは、期待するほど多くの作業ではないので、怖がらずに試してみてください: 気に入るかもしれません。

于 2013-03-01T11:27:09.473 に答える