モジュール、プロバイダー、インターフェース(コンポーネント)をセットアップする必要がありますか?シングルトンを注入できるようにするだけでも、かなりのオーバーヘッドのようです。
誰かがDagger 2を使用して簡単なシングルトンの例を提供できますか? (シングルトンを使用するたびに渡す必要がないように、コンテキストなどのシングルトンのプロパティを設定する方法も示します)
_@Inject
_コンストラクターで注釈を付けることができないものに対してのみモジュールが必要です(たとえば、フレームワークがコンテキストのようにモジュールを作成するため)。 @Injectコンストラクターを追加できない場合は、コンポーネントでもvoid inject(...)
メソッドも指定する必要があります。
ただし、_@Inject
_コンストラクターで作成できる場合、_@Inject
_はフィールド注釈としても機能します
_@Component(modules={ContextModule.class})
@Singleton
public interface SingletonComponent {
void inject(MainActivity mainActivity);
}
@Module
public class ContextModule {
Context context;
public ContextModule(Context context) {
this.context = context;
}
@Provides
Context context() {
return context;
}
}
@Singleton
public class MyOtherSingleton {
@Inject
public MyOtherSingleton() {
}
}
@Singleton
public class MySingleton {
@Inject Context context;
@Inject MyOtherSingleton myOtherSingleton;
@Inject
public MySingleton() {
}
}
_
コンストラクターパラメーターを実行することもできます
_private final Context context;
private final MyOtherSingleton myOtherSingleton;
@Inject
public MySingleton(Context context, MyOtherSingleton myOtherSingleton) {
this.context = context;
this.myOtherSingleton = myOtherSingleton;
}
_
_SingletonComponent singletonComponent = DaggerSingletonComponent.builder()
.contextModule(CustomApplication.this)
.build();
// and elsewhere
@Inject
MySingleton mySingleton;
// ...
singletonComponent.inject(this);
_
動作確認済み:
_08-23 04:39:28.418 com.zhuinden.rxrealm D/DogView: My singleton has [com.zhuinden.rxrealm.application.CustomApplication@53348a58] and [com.zhuinden.rxrealm.application.injection.test.MyOtherSingleton@5336bb74]
08-23 04:39:36.422 com.zhuinden.rxrealm D/CatView: My singleton has [com.zhuinden.rxrealm.application.CustomApplication@53348a58] and [com.zhuinden.rxrealm.application.injection.test.MyOtherSingleton@5336bb74]
_
用語シングルトンに焦点を合わせないでください。 Dagger2(daggerを忘れてdagger2を使用)は、オブジェクトのスコープを強制するために存在します。通常のスコープ(クラス、メソッド、ループ)ではなく、アーキテクチャレベルのスコープ(これらのレイヤーを定義します)。
Android=の典型的なレイヤーはApplication、Activity、Fragmentです。ご存知のように、AndroidアプリはApplicationクラスの1つのインスタンスのみを取得します。Activityクラスの多くのインスタンスFragmentクラスの多くのインスタンス。
アプリをきれいできれいに保ち、オブジェクトが属する場所にオブジェクトを保持する(セマンティクスを強化する)必要があります。これらのオブジェクトはどこかで作成する必要があります(通常、ファクトリクラス/メソッド/プロジェクトを入力する必要があります-最後の1つは冗談でした)、その作成ユーティリティはどこかに呼び出され、それらのオブジェクトをどこかからそれらが属する場所に渡す必要があります!
(通常は奇妙な名前のクラス)を入力する場所はたくさんあり、それらのオブジェクトを作成された場所から所属する場所に渡すことはかなり可能ですチャレンジ。特に、多くの異なるクラスがその特別なオブジェクトを使用する場合。
Dagger2が助けになります!基本的に、理解する必要がある2つの用語があります。コンポーネントとモジュール。
コンポーネントは注入するためにここにあります。構築する必要があるオブジェクトをクラスに注入します。コンポーネントは注入するだけで、オブジェクトは作成しません。では、だれがオブジェクトを作成しますか?
モジュールは、コンポーネントが構築する必要のあるクラスに注入するオブジェクトを作成します。モジュールには、provideInsertNameメソッドがいっぱいです。これらのメソッドは、それらを必要とするクラスに渡す必要があるオブジェクトを作成します。提供メソッドは常に新しいオブジェクトを作成するか、その提供メソッドに@Scopeアノテーションが付けられている場合、(シングルトン)既に作成されたオブジェクトを再利用します(新しいスコープアノテーションを入力する必要がありますが、それは詳細です)。提供メソッドの名前は実際には重要ではありません。重要なのは、これらのメソッドの戻り値の型です(後で役立つ情報を覚えておいてください)。
コンポーネントを入力するとき、どのモジュールがそのコンポーネントに関連付けられているかを指定する必要があり、コンポーネントのインスタンス化中に、関連付けられたモジュールインスタンスをそのコンポーネントコンストラクターに渡す必要があります。一緒に、コンポーネントとモジュールは、平均的な射出成形機を形成します。
コンポーネントのインスタンス化(Dagger2はコンポーネントのビルダークラスを生成します)たとえば、Applicationクラス内にApplicationComponentインスタンスを作成します。 ApplicationComponentによってインジェクトされるオブジェクトは1回だけ作成され、ApplicationComponentインスタンスが存在する間は存在します(インジェクション中は、再作成ではなく取得されます)。 ApplicationComponentインスタンスは存在しますが、Applicationインスタンスは存在します(so Android基本的に常に/アプリの有効期間中の環境))。
Activityクラスで同じストーリーを繰り返すことができます。 Activityクラス内にActivityComponentをインスタンス化します。そのComponentは、Activityが存在する間に存在します。 ActivityComponent(Activityクラスインスタンス)が存在する場合にのみ、ActivityComponentによって挿入されたオブジェクトが存在することに注意してください。それがDagger2の美しさです。アクティビティレイヤーに属するオブジェクトは、文字通りアクティビティレイヤーにスコープされます。
注:コンポーネントは相互に依存できます。 ActivityComponentはApplicationComponentに依存するため、ActivityレイヤーはApplicationレイヤーのオブジェクトを使用できます(ただし、他の方法ではなく、それは悪い設計です)。このようにして、コンポーネントは依存関係ツリーを形成し、オブジェクトのフェッチとインジェクションを非常に効率的にします。
これを読んだ後(おめでとうございます)、これをチェックアウトすることをお勧めします link とチェックアウト Dagger2に関するジェイク・ウォートンの講演 。