【PHP】引数にインスタンスを自動に入れる

DI(依存性注入)という処理があるのですが、
コンストラクタの引数にオブジェクトを入れて、疎結合にする処理です。
インターフェースが共通になら別のクラスに入れ替えても中の処理を書き換えることがないので、
テスト時はこっちのクラスで本番はこっちのクラスなどという書き換えが柔軟に行えます。
でもまあクラスが多くなってくると変数に放り込んでいくのもめんどくさいので、勝手にやってくないかなあという話です。

インターフェース共通と言っておきながらこの処理ではクラス名でないと動きません。

こんな感じのクラスがあるとします。

Dには引数が4つあって、うち3つはオブジェクトを入れないといけないため、$a,$b,$cをまた別個に…とやっていくと、先の定義からして結構な量書かないといけなくなるうえに入り組んででめんどくさいです。
(ほんとはこんな処理書くなよって話ですし、本番では多分書きはしませんが)
そこで次の感じの関数を投入します。

関数にしてますがメモリ上無駄な処理も入ってるのでクラスにまとめたほうがいいかと。
そしてDを作る処理は

これでOKになります。
注意としては普通の変数を引数に取るコンストラクタの場合は、デフォルト引数がないとNULLが入っちゃいます。
コンストラクタで依存性を注入することをコンストラクタインジェクションというそうです。
一方メソッドで依存性を注入することはメソッドインジェクションというみたいです。
セッターで入れる場合にはセッターインジェクションです。
んじゃクラスFのメソッドdiで依存性を注入する場合には上の関数では、

になります。
この場合には、F::di()に依存性注入のための解決を図ってますが、その下ではdiがあればdi関数を実行して依存性の注入、
ない場合にはコンストラクタに依存性の注入を行っています。
そのためコンストラクタと依存性注入するメソッド両方に引数があるとうまく動かないと思います。

セッターインジェクションは、セッター用意してる時点でDIっていうかカプセル化っていうかみたいな感じなので、
↑の方法では処理できないかと思います。
setXXX名のメンバ関数を探し出して放り込んでいくって感じで良いと思いますが、
この方法ほかの言語ならともかくPHPだとメンバ関数が増えまくって微妙なのでここでは割愛で。

ここではどのクラスも引数をそのまま捨ててますが、普通は受け取ったらメンバ変数に入れると思うので使う用ならそうしてください。
という感じのまた役に立つかどうかわからない処理を。