2017-11-03 7 views
4

一部のIoCコンテナでは、コンテナで実行できない引数をコンストラクタに含めることができます。これはMicrosoft.Extensions.DependencyInjectionライブラリとIServiceProviderで可能ですか?そうでない場合は、この種の問題に対するきれいな解決策は何ですか?例えば.NETコアのオプションのコンストラクタインジェクション引数

class InContainer 
{ 
    public InContainer(NotInContainer dependency) { ... } 
} 

class Consumer 
{ 
    public Consumer(IServiceProvider serviceProvider) 
    { 
     NotInContainer currentDependency = ... // from some other source 
     // passing the anonymous object here is not supported, 
     // but I would like to 
     InContainer = serviceProvider.GetService<InContainer>(
      new { dependency = currentDependency } 
     ); 
    } 
} 
+0

登録中、またはインスタンス単位での意味ですか? –

答えて

2

通常、この場合は工場を手動で作成します。

public class TheFactory 
{ 
    public TheFactory(SomeType fromContainer) 
    { 
     _fromContainer = fromContainer; 
    } 

    public IProduct Create(SomeOtherType notFromContainer) => new TheProduct(_fromContainer, notFromContainer); 

    private readonly SomeType _fromContainer; 

    private class TheProduct : IProduct 
    { 
     // ... 
    } 
} 

コンテナの製品ごとの依存関係が必要な場合は、工場のCreateで解決する必要があります。あるいは、例えば工場は容器からFuncを得ます。

+0

私はその工場が「IDisposable」を追跡し、それらをきれいにすることができると思います。 –

+0

'Create'への呼び出しを' new'と同じように扱うならば、それは呼び出し側に属するインスタンスを作成する必要はないでしょう。 – Haukinger

0

あなたの例では、あなたはランタイム値currentDependencyserviceProvider提供します。 hereで説明されているように、アプリケーションコンポーネントは構築時にランタイムデータを必要としません。解決策は、その記事で説明したように、あなたのデザインをリファクタリングすることです。オプションの引数について

いくつかのDIコンテナは、オプションの引数をサポートし、それにそれらを使用することをお勧めしますしないという事実。実際には、注入コンストラクタ引数は決してオプションであってはなりません。

としてはthis記事で説明:

オプションの依存関係は、それが供給していないとき、依存関係への参照がnullになることを意味します。ヌル参照は、ヌルケースに対して特定のロジックを必要とするため、コードを複雑にします。ヌル参照を渡す代わりに、呼び出し元は、動作のない実装、つまりNull Object Patternの実装を挿入することができます。

ない場合は、この種の問題のためのクリーンな解決策は何ですか?実際には、オプションのコンストラクタの依存関係をサポートしているDIコンテナを用いた場合でも述べたように

は、Null Object patternは、このためのソリューションです。

+0

しかし、OPの依存関係はオプションではありません。コンテナ内には存在しないため、解決時に提供したいと考えています。 – Evk

+0

@ Evk:私の更新プログラムがあなたのコメントを通過しました。 – Steven

+0

はい、それは理にかなっていますが、答えの最初の部分は質問には関係していないようです。 – Evk