1. ホーム
  2. c#

[解決済み] バスタードインジェクションに代わるものはありますか?(デフォルトコンストラクタを使った貧乏人インジェクションです。)

2022-08-31 05:45:26

質問

私は、いくつかのケースで "bastard injection" を使用したくなることがよくあります。 私が "適切な" 依存性注入コンストラクタを持っているとき。

public class ThingMaker {
    ...
    public ThingMaker(IThingSource source){
        _source = source;
    }

しかし、そうすると、私が意図しているクラスは パブリックAPI (他の開発チームが消費するクラス) のために、最も必要とされる依存関係を持つデフォルトの "bastard" コンストラクタを書くことより良いオプションを見つけることはできません。

    public ThingMaker() : this(new DefaultThingSource()) {} 
    ...
}

理想的には、そのような依存関係はなく、コンシューマは常に彼らが望むどんなIThingSourceでもインジェクトすることができることです。 しかし、これではあまりにも使いにくい。コンシューマはThingMakerを立ち上げてThings作りに取り掛かり、数ヶ月後に必要なときに他のものをインジェクトしたいのである。 このため、私の意見では、いくつかのオプションしか残っていません。

  1. ThingMaker の消費者に、IThingSource を理解し、ThingMaker が IThingSource とどのように相互作用するかを理解し、具象クラスを見つけるか書くかして、コンストラクタ呼び出しでインスタンスを注入するように強制することです。
  2. ろくでなしのコンストラクターを省略し、別のファクトリー、コンテナー、または他のブートストラップ クラス/メソッドを提供する。何らかの方法で消費者に自分自身の IThingSource を書く必要がないことを理解させ、ThingMaker の消費者にファクトリーまたはブートストラッパーを見つけ理解しそれを使用するように強制します。
  3. コンストラクターを維持し、コンシューマーがオブジェクトを "new up" して実行できるようにし、DefaultThingSource へのオプションの静的依存に対処する。

少年よ、#3 は確かに魅力的に見えます。 他の、より良いオプションはありますか? #1や2にはその価値がないように思えます。

どのように解決する?

私が理解する限り、この質問は、いくつかの適切なデフォルトで疎結合のAPIを公開する方法に関するものです。この場合、あなたは良い ローカルデフォルト があるかもしれませんが、その場合、依存関係はオプションと見なすことができます。に対処する一つの方法は オプションの依存関係 を扱う一つの方法は プロパティ・インジェクション の代わりに コンストラクタ・インジェクション - 実際、これはプロパティ・インジェクションのためのポスターシナリオのようなものです。

しかし、バスタード・インジェクションの本当の危険性は、デフォルトが 外国のデフォルト である場合です。なぜなら、デフォルトのコンストラクタが、デフォルトを実装するアセンブリに望ましくない結合を引きずることを意味するからです。しかし、私がこの質問を理解するように、意図されたデフォルトは同じアセンブリに由来するものであり、その場合、私は特に危険を見いだすことはありません。

いずれにせよ、私の以前の回答の1つで説明したように、Facadeを考慮することもできます。 依存性注入 (DI) "friendly" ライブラリ

ちなみに、ここで使われている用語は、パターン・ランゲージの 拙著 .