拡張メソッドRegisterWithContext
を使用すると、消費コンポーネントに関する情報を使用してインスタンスを構築できるようにする述語を登録します。この情報は、拡張メソッドによって述部に供給されます。
これは、消費タイプごとに完全に異なるインスタンスを構築することができるため、一時的ではなく他の何かの登録を行うと、非常に奇妙な動作につながる可能性があることを意味します。消費した場合でも、あなたはこの登録シングルトンを作りたい場合、これは問題を引き起こす
container.RegisterWithContext(c =>
(ILogger).container.GetInstance(
typeof(Logger<>).MakeGenericType(c.ImplementationType)));
:例えばあなたがT
がかかる部品の種類があるLogger<T>
実装を作成抽象化の登録を想像してみて同じインスタンスが各コンシューマに注入されるため、コンポーネントはシングルトンです。それぞれの消費者は独自のクローズジェネリック版、すなわちLogger<Consumer1>
,Logger<Consumer2>
、Logger<Consumer3>
などを必要とするため、独自のインスタンスを必要とします。代わりに、非常に消費者は同じインスタンスを取得します。最初に解決されたコンシューマ用に作成されたインスタンス。これは明らかにひどいです。
Scopeされたインスタンスを使用する場合も同様の問題が存在します。スコープの期間中は同じインスタンスを取得しますが、これは通常はあなたが望むものではありません。インスタンスはコンテキスト依存でなければなりません。
これは、Simple Injector v2のマニュアルで提供されたRegisterWithContext
拡張メソッドの深刻な制限です。これはあまりにも制限されていたため、Simple Injector v3にはRegisterWithContext
拡張メソッドに代わる組み込みのRegisterConditional
メソッドが含まれるようになりました。 v3のドキュメントはもうRegisterWithContext
を参照することはありません。代わりにRegisterWithContext
を使用するようにアドバイスします。
RegisterConditional
を使用する方法文書describesと、次の例を示しています。この登録の述語は登録が本当に条件、単に文脈ではない、true
を返すので
container.RegisterConditional(
typeof(ILogger),
c => typeof(Logger<>).MakeGenericType(c.Consumer.ImplementationType),
Lifestyle.Singleton,
c => true);
を。
このコードを使用すると、消費コンポーネントに固有のLogger<T>
を返すことができますが、閉じた各Logger<T>
タイプのインスタンスが最大で1つも存在することが保証されます。したがってシングルトン。
新しいRegisterConditional
と古いRegisterWithContext
の主な違いは、インスタンスを作成するためのファクトリデリゲートを提供できないことです。 RegisterConditional
を使用すると、Simple Injectorがインスタンスの作成(代理人ではなく)の制御を行い、パイプラインに完全に組み込むタイプの作成が可能になり、Simple Injectorが登録されたコンポーネントとその依存関係を検証および診断できるようになります。
ありがとうございます。本当に役に立ちます。 –