16

[ImportingConstructor]でプロパティを装飾するよりも適切な時期を理解しようとしてい[import]ます。それは個人的な好みですか、それともクラスを他の DI コンテナーで構築できるようにするものですか、それとも利点があり[import]ますか?

パブリック プロパティを公開したくないが、MEF はプライベート フィールドも解決するので、メリットはどこにあるのでしょうか。

4

4 に答える 4

25

を使用する際の問題[Import]は、オブジェクトの作成を、作成と初期化という2つの明確で観察可能なフェーズに分割することです。ここで[ImportingConstructor]、これを他のすべての.Netオブジェクトの場合とまったく同じように単一フェーズとして維持できます。

この違いは、さまざまな方法で観察できるようになります

  1. フィールドにnewを追加する[Import]と、タイプの論理コントラクトが変更されます。それでも、それは公共または使用契約を変更しません。これは、以前にコンパイルされたコードは、オブジェクトの依存関係が変更された場合でもコンパイルを継続することを意味します(単体テストを考えてください)。これにより、コンパイル時のエラーが発生し、実行時のエラーになります。
  2. がある場合、コードコントラクトは使用できません[Import]。契約検証エンジンは、すべてのフィールドが値として存在する可能性があることを適切に認識し、フィールドをnull使用するたびにチェックする必要があります。
  3. オブジェクトには、初期化時に設定され、後でリセットされることのないフィールドを論理的に含めることができreadonlyますが、通常のC#オブジェクトのようにこれを表現することはできません。
于 2012-05-31T20:17:15.160 に答える
11

純粋に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これはいくつかの方法で役立ちます。

  1. タイプに必要な依存関係を表現します。これにより、タイプが使用可能な状態で作成されるようにするために満たす必要のある初期化コントラクトが形成されます。
  2. サービスがタイプに渡されるようにすることで、ランタイムエラーのリスクを減らします。

コードコントラクト(@JaredParで言及されている)を使用してコンパイル時に静的チェックを含めることで、この設計をさらに改善できます。

MEFに関しては、MEFが型のすべてのインポートを満たすことができない場合に例外をスローし、初期化()とsの両方の後にのみ型を返すため、[Import]代わりにを使用することで回避できます。[ImportingConstructor][ImportingConstructor][Import]

コンストラクター注入が一般的に好ましい。

于 2012-06-01T11:04:49.783 に答える
5

を使用[ImportingConstructor]すると、エクスポートとして機能する1つのクラスがその依存関係をインポートできるようになります。これにより、具体的なオブジェクトの依存関係をその実装から切り離すことができるため、アーキテクチャが劇的に簡素化されます。

通常、[ImportingConstructor]それ自体が。としてマークされているタイプで使用します[Export]。型が作成されると、コンストラクター引数はMEFによって提供されます。

于 2012-05-31T20:17:30.983 に答える
0

再構成は、コンストラクター パラメーターでもサポートされていません。

于 2013-11-07T23:10:07.367 に答える