[ImportingConstructor]
でプロパティを装飾するよりも適切な時期を理解しようとしてい[import]
ます。それは個人的な好みですか、それともクラスを他の DI コンテナーで構築できるようにするものですか、それとも利点があり[import]
ますか?
パブリック プロパティを公開したくないが、MEF はプライベート フィールドも解決するので、メリットはどこにあるのでしょうか。
を使用する際の問題[Import]
は、オブジェクトの作成を、作成と初期化という2つの明確で観察可能なフェーズに分割することです。ここで[ImportingConstructor]
、これを他のすべての.Netオブジェクトの場合とまったく同じように単一フェーズとして維持できます。
この違いは、さまざまな方法で観察できるようになります
[Import]
と、タイプの論理コントラクトが変更されます。それでも、それは公共または使用契約を変更しません。これは、以前にコンパイルされたコードは、オブジェクトの依存関係が変更された場合でもコンパイルを継続することを意味します(単体テストを考えてください)。これにより、コンパイル時のエラーが発生し、実行時のエラーになります。[Import]
。契約検証エンジンは、すべてのフィールドが値として存在する可能性があることを適切に認識し、フィールドをnull
使用するたびにチェックする必要があります。 readonly
ますが、通常のC#オブジェクトのようにこれを表現することはできません。純粋にMEFの観点から考えるのではなく、より広い意味でクラスの設計を見てください。通常、クラスを設計する場合、関連するプロパティのセットがあります。これらはサービスである可能性があります。
public class MyService
{
public ILogger Logger { get; set; }
public void SaySomething()
{
Logger.Log("Something");
}
}
これで、先に進んでそのインスタンスを作成できます。
var service = new MyService();
そして今、私がこの方法を試して使用すると、次のようになります。
service.SaySomething();
Logger
プロパティも初期化する必要があることを明示的に知らない場合:
var service = new MyService() { Logger = new ConsoleLogger() };
(また):
var service = new MyService();
service.Logger = new ConsoleLogger();
その後、エラーは実行時まで明らかになりません。クラスを再定義する場合:
public class MyService
{
private readonly ILogger _logger;
public MyService(ILogger logger)
{
if (logger == null) throw new ArgumentNullException("logger");
_logger = logger;
}
public void SaySomething()
{
_logger.Log("Something");
}
}
ここで、のインスタンスを作成しようとすると、オブジェクトを正しく初期化するために、MyService
この追加のサービス()を明示的に提供する必要があります。ILogger
これはいくつかの方法で役立ちます。
コードコントラクト(@JaredParで言及されている)を使用してコンパイル時に静的チェックを含めることで、この設計をさらに改善できます。
MEFに関しては、MEFが型のすべてのインポートを満たすことができない場合に例外をスローし、初期化()とsの両方の後にのみ型を返すため、[Import]
代わりにを使用することで回避できます。[ImportingConstructor]
[ImportingConstructor]
[Import]
コンストラクター注入が一般的に好ましい。
を使用[ImportingConstructor]
すると、エクスポートとして機能する1つのクラスがその依存関係をインポートできるようになります。これにより、具体的なオブジェクトの依存関係をその実装から切り離すことができるため、アーキテクチャが劇的に簡素化されます。
通常、[ImportingConstructor]
それ自体が。としてマークされているタイプで使用します[Export]
。型が作成されると、コンストラクター引数はMEFによって提供されます。
再構成は、コンストラクター パラメーターでもサポートされていません。