configuration - golang wire github




なぜあなたは構成なしでDependency Injectionを望んでいますか? (6)

.NETでPRISMについて読むべきです(.NETで複合アプリケーションを実行するのがベストプラクティスです)。 これらのベストプラクティスでは、各モジュールが共有コンテナ内で実装タイプを「公開」します。 このようにして、各モジュールは「誰がこのインタフェースの実装を提供するか」に対する明確な責任を持ちます。 PRISMの仕組みを理解するときは、十分に明確になると思います。

この質問で素晴らしい答えを読んだ後、私はJustin Etheredgeのスクリーンキャストを見ました。 あなたのコードからDIを正しく取得できるように、セットアップは最小限に抑えられています。

さて、私にとっては、構成ファイルを使用しないDIフレームワークを使用する理由は何ですか? これは、DIインフラストラクチャを使用することの全体的なポイントではないので、コードをビルド/リリースした後に、行動を変えることができますか?

誰か私にNinjectのような構成されていないDIを使って検証する良いユースケースを教えてもらえますか?


コントロールの反転を使用すると、クラスを可能な限り小さくするのに役立ちます。 たとえば、ファイルを待ってから一連のプロセスを実行するWindowsサービスがあるとします。 プロセスの1つはZIPに変換してから電子メールで送信することです。

public class ZipProcessor : IFileProcessor
{
  IZipService ZipService;
  IEmailService EmailService;

  public void Process(string fileName)
  {
    ZipService.Zip(fileName, Path.ChangeFileExtension(fileName, ".zip"));
    EmailService.SendEmailTo(................);
  }
}

あなたがこれを行うために専用のクラスを持つことができるとき、なぜこのクラスは実際にジップとメールを行う必要がありますか? 明らかにあなたはそうではありませんが、それは私の指摘につながるだけです:-)

Zipを実装しないことに加えて、クラスがサービスを実装するクラスをなぜ知っているのでしょうか? このプロセッサーのコンストラクターにインターフェイスを渡すと、特定のクラスのインスタンスを作成する必要はなく、ジョブを実行するために必要なものがすべて与えられます。

DICを使用すると、特定のインターフェースを実装するクラスを構成し、インスタンスを作成するだけでクラスに依存関係を注入することができます。

var processor = Container.Resolve<ZipProcessor>();

今では、クラスの機能性を共有機能からきれいに分離するだけでなく、消費者/プロバイダーが互いの明示的な知識を持たないようにしています。 これにより、同時に考慮する要素が少なくなるため、コードを読みやすくなります。

最後に、単体テストでは、偽の依存関係を渡すことができます。 あなたのZipProcessorをテストするとき、嘲笑されたサービスはクラスが実際にメールを送信しようとするのではなく電子メールを送信しようとしたことを単にアサートします。

//Mock the ZIP
var mockZipService = MockRepository.GenerateMock<IZipService>();
mockZipService.Expect(x => x.Zip("Hello.xml", "Hello.zip"));

//Mock the email send
var mockEmailService = MockRepository.GenerateMock<IEmailService>();
mockEmailService.Expect(x => x.SendEmailTo(.................);

//Test the processor
var testSubject = new ZipProcessor(mockZipService, mockEmailService);
testSubject.Process("Hello.xml");

//Assert it used the services in the correct way
mockZipService.VerifyAlLExpectations();
mockEmailService.VerifyAllExceptions();

だから短いです。 01にするといいでしょう:消費者が必要なサービスを提供しているプロバイダーを明示的に知るのを防ぎます。つまり、コードを読むときにすぐに理解することが少なくなります。 02:ユニットテストを簡単にします。

ピート


依存性のある注入ユニットテストは、テストするオブジェクトに実際のオブジェクトの代わりにモックを注入できるので、セットアップが非常に簡単になります。 あなたはそれのための構成を必要としません、ちょうどユニットテストコードのモックを作成し、注入します。


依存性注入パターンを適用するためにDIフレームワークを使用する必要はありません。 コードの再コンパイルとは別に設定が必要ない場合は、単にオブジェクトを作成するための静的ファクトリメソッドを使用することができます。

したがって、すべてのアプリケーションをどのように構成したいかによって異なります。 コードの再コンパイルをせずに設定/プラグ可能にしたい場合は、テキストファイルまたはXMLファイルで設定できるものが必要です。


私は構成なしで DIフレームワークを望むとは思わない。 私はあなたが必要とする設定でDIフレームワークが必要だと思います。

私は例として春を取るでしょう。 「旧式」では、すべてをすべてXMLファイルに入れて、すべてを構成可能にしていました。

完全に注釈を付けられた体制に切り替えるとき、yorアプリケーションに含まれるコンポーネントの役割を基本的に定義します。 したがって、特定のサービスは、例えば、アプリケーションの「スタブ」バージョンに属する別の実装が存在する「通常の実行時」のための1つの実装を有することができる。 さらに、統合テストのための配線を行う場合は、3番目の実装を使用している可能性があります。

このように問題を検討すると、ほとんどのアプリケーションに実行時に非常に限定されたコンポーネントロールしか含まれていないことがすぐにわかります。これらはコンポーネントの異なるバージョンを実際に使用する原因になります。 通常、コンポーネントの実装常にこのロールにバインドされています。 それは実際にその実装の理由です。

したがって、「構成」で必要なコンポーネントの役割を指定するだけであれば、構成をまったく使わずに済むようになります。 もちろん例外はいつもありますが、代わりに例外を処理するだけです。


私はkrosenvoldの道を歩いていますが、ここではテキストが少ないだけです。ほとんどのアプリケーションでは、必要な "サービス"ごとに1つの実装があります。 各オブジェクトが各サービスの実装を10個以上必要とするアプリケーションを記述するのではなく、 したがって、これがデフォルトの実装であり、このサービスを使用するすべてのオブジェクトの99%がそれに満足しているという単純な方法を持つことが理にかなっています。

テストでは、通常、特定のモックアップを使用します。そのため、手動で配線するので、そこに設定する必要はありません。

これは、コンベンションオーバーコンフィグレーションのすべてについてです。 ほとんどの場合、設定は単純に、DIフレームワークが既に知っていなければならない何かのダンプです。

私のアプリケーションでは、実装をルックアップするためのキーとしてクラスオブジェクトを使用していますが、「キー」はデフォルトの実装になります。 私のDIフレームワークが設定でオーバーライドを見つけることができない場合、それは単にキーをインスタンス化しようとします。 1000以上の "サービス"で、私は4つのオーバーライドが必要です。 それは書くには役に立たないXMLがたくさんあります。





inversion-of-control