2013-01-21 5 views
8

プロジェクトで依存関係の注入を一貫して使用しようとしているところですが、問題が発生しました。PHPコンストラクタの引数が利用できないときの依存関係の注入

MongoDBクエリを処理するクラスを作成しています。私は問題なく、コンストラクタへの依存としてMongoClientを渡します。しかし、オブジェクトをインスタンス化するために必要な変数がインスタンス化時に利用できないときに、依存関係をどのように処理するのですか?

特に、MongoCollectionメソッドのfindOneのラッパーがあります。文字列を渡すと、現在の(古いコードで)その文字列が "新しいMongoId($ _ id)"でMongoIdに変換されます。それをfind関数に使用します。

私は依存性注入について学んだことから、 "新しいMongoId"を持つことは悪い考えです。文字列をMongoIdに変換する関数のテストケースを書くのは難しいでしょう。

しかし、MongoIdクラスがコンストラクタでid文字列を受け取ったときに、どのようにして注入を処理するのですか?

$getMongoId = function($id){ 
    return new MongoId($id); 
}; 

class MyMongo 
{ 
    function __construct(MongoClient $client, Closure $mongoIdGetter){...} 
} 

で、[この問題を解決するために、編集:

私は働くだろうそのことを考えてきた唯一のものは、何かのように動作するクラスのコンストラクタに閉鎖に渡すことです最後の部分]

これは正しい方法ですか?もちろん、DiCを使用している場合はそれを実行できますが、コンストラクタを閉じる必要があります。私は自分の依存関係を注入するのはあまりにも独断的すぎるのだろうか?新しいクラスで "new MongoId($ _ id)"を使って簡単に修正できると思います。

答えて

1

しかし、オブジェクトのインスタンス化に必要な変数がインスタンス化時に利用できない場合、どうすれば依存関係を処理できますか?

あなた自身で処理する前に、PHPで致命的なエラーが発生します。型パラメータを使用するか、またはそれらをデフォルトで定義しない場合、nullそのパラメータが関数に渡されないと、PHPは致命的なエラーになります。私は依存性注入について学んだことから、

、「新しいMongoId」を持つことは悪い考えであり、私はそれはそれは難しいMongoIdに文字列を変換する関数のためのテストケースを書くことになりますことを既に知っています。

これは(PHPUnitで)ですか?

$this->assertInstanceOf('\MongoId', $getMongoId($id_string)); 

しかし、どのようにMongoIdクラスは、コンストラクタのID文字列を取るとき、私は注射を扱うのですか?

ダンノーそれはあなたが意味することですが、MongoIdの処理の結果のみをテストする必要があります。

ご質問の最後のビットが少し緩んでいます。実際のPHP(つまり$__construct)ではないためです。

私は、なぜそのようなクラスに関数を押し込む必要があるのか​​分かりません。

function findById($id){ 
    if(!$id instanceof \MongoId) $id = new MongoId($id); 
    return $this->getCollection()->findOne($id); 
} 

あなたはそれ以上のものを必要としない、それはすでにユニットがテストされているので、あなたがMongoIdのコンストラクタをテストする必要はありません、あなたが代わり単位でなければなりません:私は何であるか、私はほとんどの時間を持っていることを意味しますあなたの公開APIをテストしてください。オブジェクトの作成は、彼らの唯一の目的であり、あなたが簡単に置き換えることができますので、「新しい何か」ハードコーディングされた依存関係を持つようにそれは大丈夫と考えられている工場で

class MongoFactory 
{ 
    public function createMongoDb($id) 
    { 
     return new MongoId($id); 
    } 
} 

:代わりにあなたが工場を使用することができますクロージャの

+0

ありがとうございます - $ __の構造は、脳のおならです。私はあなたが上記の「ハンドル」と言うとき、私はエラー処理に言及していないので、言葉の一般的な感覚を部分的に誤解していると思います。 – Karptonite

+0

@Karptoniteああ、なぜあなたは構造にMongoIdセッターを入れたいのか分かりますが、私は依存関係を理解し​​ていますが、実際に 'find'関数を使うまでは必要ありません。ユニットテストのために必要なのは、 '_id'の文字列を入力している間に存在するはずのドキュメントを返すpublic関数の応答をチェックすることです。ユニットテストをMongoDBドライバ自体に拡張しないでください。 – Sammaye

+0

私は依存性注入については新しいですが、あなたのような関数を使ってコード内に「新しいMongoId」を書いたのは、一般的には悪い考えです。例えば、私がMongoIdのメソッドを私のコードがそれらのメソッドを適切に呼び出すことを保証するために、私はそれを嘲笑することができませんでした。確かに、それは私が今やっていることではありません。 – Karptonite

2

他の工場と一緒に。

お客様の消費者クラス(MyMongo)は、MongoFactory(またはその場合はそのインターフェイス)への依存性を持つようになりました。これは簡単に「注入」できます。

関連する問題