いくつかのログ機能を子クラスに公開する基本コントローラー クラスがあります。このロギング依存関係は、コンストラクターによって注入されます。単純化されたコードを提供するために、これはすべてがどのように見えるかです:
public abstract class LogControllerBase : Controller
{
private readonly ILogger logger = null;
protected LogControllerBase(ILogger logger)
{
this.logger = logger;
}
}
私の子コントローラーにも独自の依存関係があるため、次のようになります。
public class SomeController : LogControllerBase
{
private readonly IService service = null;
[ImportingConstructor]
public SomeController(ILogger logger, IService service)
: base(logger)
{
this.service = service;
}
}
これらのコンストラクターを使用して、単体テストで依存性注入を簡単に実行できるようにしていますが、本番環境では、すべての構成は MEF によって行われます (する必要があります)。MEF を使用してコントローラーをインスタンス化するカスタム コントローラー ファクトリ クラスを使用しています。
要約すると:
- 独自の依存関係を持つ基本抽象コントローラー クラスがあります。
- インポートを使用して MEF によって注入されたパラメーターを取得する子孫コントローラーがあります (つまり、依存関係と基本クラスの依存関係です)。
- 単体テストは MEF を使用しないため、コンストラクター パラメーターにモックが挿入されます。
問題
これはすべて私に水を与えますが、MEF の考え方は異なります。このコードをコンパイルして実行すると、次の例外が発生します。
GetExportedValue は、前提条件のインポート 'SomeController..ctor (Parameter="logger", ContractName="ILogger")' が設定される前に呼び出すことはできません。
コンストラクターのパラメーターとして使用されるすべてのインターフェイス型には属性がInheritedExport
設定されており、具体的な実装も含まれているため、期待どおりに機能するはずです。
同じではない作業代替
これらのプライベートフィールドで直接インポートを行うことで別のアプローチを試みると、すべてうまくいくようです。
public abstract class LogControllerBase : ControllerBase
{
[Import]
private ILogger logger = null;
protected LogControllerBase() { }
}
public class SomeController : LogControllerBase
{
[Import]
private IService service = null;
public SomeController() { }
}
したがって、これは機能しますが、同じではありません...依存関係の挿入のためにここにコンストラクターを追加できますが、2セットのコンストラクターがあり、ユニットテストを行うときに、依存関係がないためもちろん間違っているパラメーターなしのコンストラクターを使用する可能性があります設定されます。本物でもモックでもない。
質問
依存性注入コンストラクターを として設定することにより、コンストラクターに具体的な実装を注入することにより、MEF がコントローラーを作成するように説得するにはどうすればよいImportingConstructor
ですか?