これは部分的には前回の回答のコメントの一部であると思いますが、私は推論のいくつかを少し例証しようとしました。
注入されたオブジェクトの寿命を管理する領域に入ると、おそらくこれらのオブジェクトのファクトリを作成する必要があります。
基本的な問題は、コンポジションルートが、オブジェクトを作成するために必要なコールの環境コンテキストを認識していないことです。
私は一歩踏み出してこの時点で説明する必要があると思います。
依存性注入に関する知恵は、コードのエントリポイントの近くにいくつかの構成ルートを持つことです。これにはウェブで見つけるのが難しくない多くの理由がありますので、ここでは取り上げません。
コンポジションルートは、インターフェイス(通常はオブジェクトですが)をインプリメントにマップする場所です。この時点で利用可能な情報をコンストラクタに渡すことができます。したがって、コンポジションルートの実行時にライフタイムが現在のオブジェクトへの参照を渡すことができます。
ただし、作成するオブジェクトのライフタイムとコンポジションルートのライフタイムが重ならない場合は、オブジェクトを作成する必要があるまでコンストラクタの実行を延期する必要があります。これが工場を持つ必要がある理由です。この時点で、ファクトリメソッドをマッピングに渡して、オブジェクトを生成するのに必要な情報を渡すことができますが、コンポジションルートが実行されていないときに作成が行われるようにすることができます。
ファクトリクラスは必要ありません。このファクトリメソッドはうまくいきますし、さらにファクトリメソッドをインライン化することもできます。したがって、コードオーバーヘッドは合成ルートにオブジェクトを作成する場合に比べてあまり重要ではありません。
最初のサービスが最初のサービスに依存する2つのサービスを持つプロジェクトがあり、最初のサービスを作成するときに2番目のサービスのライフタイムを開始したい場合は、次のようなものがあります。 (私は、コード例を与えることをninject使用していますが、私は他のIOCのコンテナが、この点でも同様に動作することを期待しています。)
`
public class Service1:IService
{
private Func<IService>serviceFactoryMethod _Service2Factory;
public Service1(Func<IService>service2FactoryMethod)
{
_Service2Factory=service2FactoryMethod;
}
public void DoSomethingUsingService2()
{
var service2=_Service2Factory();
service2.DoSomething();
}
}
public class MainClass
{
public void CompositionRoot()
{
var kernel= new StandardKernel();
kernel.Bind.ToMethod(m=>
{
return new Service1(m.Kernel.Get<IService2>());
}
}
}
`
この例を使用すると、アプリケーションの寿命を管理する方法を扱っていません。 、プレイヤー、ゲームのライフスパンなどが含まれていますが、従属注入に関連する生涯の問題を取り除く方法についての十分な手がかりを与えられれば幸いです。
サイドノート:Ninjectを使用すると、Service2の有効期間を管理してService1の有効期間を過ごすことができるようになります。たとえば、ゲームの各インスタンスが独自のスレッドで実行されていることが分かっている場合(OK、これは多分そうではないかもしれません)、InThreadScopeをゲームに使用する可能性があります。
ライフスタイル/ライフタイムの設定は、通常、ほとんどのDIコンテナでサポートされています。どのプラットフォームとDIフレームワークについて話していますか? – Steven
いくつかのコンテナは、ある程度のライフタイム管理をサポートしていますが、IPlayerをパラメータとするクラスを想像してください(この場合、多くのクラスがそうします)。単一のコンテナがある場合、ランタイムデータのファクトリを必要とせずにこのクラスをどのように登録しますか?私は、ライフサイクルごとに別々のコンテナを作成することを実験しましたが、複数のライフスパンに関わる懸念がある場合には、さまざまな部分を結びつけるためにまだ苦労しています。 –
この場合は.NET/C#ですが、私は実際にこの設計問題をより一般的に解決する方法に興味があります。特に、私が対象としているすべてのプラットフォームでは利用できない可能性があるため、特定のコンテナにあまり依存したくありません。参考文献: –