私は怠け者で、フィールド注射をほとんど使用していました。空のコンストラクタを提供していただけで、私の@Injectフィールドを置いてみました。しかしフィールドインジェクションにはトレードオフがあるので、いつフィールドを使うのか、いつコンストラクタインジェクションを使うのかを決めるのに役立つ簡単なルールを考案しました。私のロジックに間違いがある場合、または追加する追加の考慮事項がある場合は、いかなるフィードバックも感謝します。ダガー2:コンストラクタインジェクションをいつ使うのか、フィールドインジェクションをいつ使うのですか?
同じページ上にあるために、まずいくつかの明確化:
コンストラクタ・インジェクション:
@Inject
public SomeClass(@Named("app version") String appVersion,
AppPrefs appPrefs) {...
フィールド注入と同じ
:
public class SomeClass {
@Inject
@Named("app version") String mAppVersion;
@Inject
AppPrefs appPrefs;
はルール1:フィールドを使用しなければなりません私がオブジェクトの作成を制御しない場合は、注入()(Androidのアクティビティやフラグメントと考える)私のオブジェクトを作成し、それを私に処理するフレームワーク(非ダガー認識)のフレームワークでは、インスタンスを受け取った後に手動で注入するしかありません。
ルール2:Dagger 2を使用しない別のプロジェクトでクラスを使用する場合は、コンストラクタインジェクションを使用する必要があります。他のプロジェクトでDaggerを使用しない場合はDIを使用できないため、ユーザはnew
を使用してオブジェクトを「古い」方法で作成する必要があります。
ルール3:単体テストの作成が容易であるため、クラス階層を扱うときはPREFERコンストラクタを注入します。
明確化:
package superclass;
public class SuperClass {
@Inject
HttpClient mHttpClient;
...
}
:
フィールドインジェクションを使用して、以下の構造を考えます。
package differentpackage;
public class SubClass extends SuperClass {
public SubClass() {
}
}
私はディレクトリtest/java/differentpackage
にためのユニットテストを作成していたとき、私はHttpClient
を注入することができるようにするために全体のDIインフラを立ち上げざるを得ません。私はこのようなコンストラクタ・インジェクション使用していた場合はこれとは対照的に、:私のユニットテストで
public class SuperClass {
private final HttpClient mHttpClient;
@Inject
public SuperClass(HttpClient httpClient) {
mHttpClient = httpClient;
}
}
を私は単純にできます
HttpClient mockHttp = mock(HttpClient.class);
Subclass tested = new Subclass(mockHttp);
// tests
だから基本的に今私は他の極端に午前:私は主に依存する傾向がありますコンストラクタインジェクションを行い、フィールドインジェクションを使用するのは、 'Rule 1'が適用された場合のみです。私はコンストラクタで持っている唯一の「問題」は注入 は、「終了」のクラスのコンストラクタは、時にはかなりのパラメータで過負荷になっていることであり、彼らはこのように冗長と醜い:
@Inject
public ModelMainImpl(@Named("app version") String appVersion,
AppPrefs appPrefs,
LoginPrefs loginPrefs,
@ForApplication Context appContext,
NetworkInfoProvider networkInfoProvider,
AndroidEventPoster androidEventPoster,
Session session,
ForgeExchangeManager exchangeManager,
HttpFunctionality httpFunctionality,
@Named("base url") String baseUrl,
@Named("forge result producer") ResultProducer<ForgeExchangeResult> resultProducer
) {
みんな、あなたのルールには何ですかコンストラクタとフィールドインジェクションのどちらかを選択しますか?私は何かが欠けている、私のロジックにエラーがありますか?
https://stackoverflow.com/questions/39207845/android-dagger-2-inject-versus-provides これを見ると、良い洞察を提供します –