2017-09-13 9 views
1

@Component.Builderがダガー2でどのように機能するかを説明するthis偉大なチュートリアルを読んでいます。著者は良い仕事をしていますが、記事はまっすぐですが、まだ分かりにくいです:コンポーネントダガーの理解2 @ Component.Builder注釈

@Singleton 
@Component(modules = {AppModule.class}) 
public interface AppComponent { 

    void inject(MainActivity mainActivity); 
    SharedPreferences getSharedPrefs(); 
} 

モジュール:

@Module 
public class AppModule { 

    Application application; 

    public AppModule(Application application) { 
     this.application = application; 
    } 

    @Provides 
    Application providesApplication() { 
     return application; 
    } 
    @Provides 
    @Singleton 
    public SharedPreferences providePreferences() { 
     return application.getSharedPreferences(DATA_STORE, 
           Context.MODE_PRIVATE); 
    } 
} 
ダガー2のデフォルトの実装は次のようになります

コンポーネントインスタンス化:

DaggerAppComponent appComponent = DaggerAppComponent.builder() 
     .appModule(new AppModule(this)) //this : application 
     .build(); 

記事によると、私たちは@Component.Builder@BindsInstanceアノテーションを使用してモジュールのコンストラクタに渡す引数を避けることによって、さらにこのコードを簡素化することができ、その後、コードは次のようになります。

成分:

@Singleton 
@Component(modules = {AppModule.class}) 
public interface AppComponent { 
    void inject(MainActivity mainActivity); 
    SharedPreferences getSharedPrefs(); 

    @Component.Builder 
    interface Builder { 
     AppComponent build(); 
     @BindsInstance Builder application(Application application);  
    } 

}

メートルodule:

@Module 
public class AppModule { 

    @Provides 
    @Singleton 
    public SharedPreferences providePreferences(
            Application application) { 
     return application.getSharedPreferences(
            "store", Context.MODE_PRIVATE); 
    } 
} 

とコンポーネントのインスタンス化:

DaggerAppComponent appComponent = DaggerAppComponent.builder() 
      .application(this) 
      .build(); 

私はほとんど上記のコードがどのように機能するかを理解するが、ここで私は理解していない部分である:どのように我々はapplication(this)appModule(new AppModule(this))から手に入れました私たちはコンポーネントをインスタンス化していますか?

私は質問がはっきりと感謝してくれたことを願っています。

答えて

4

TL;あなたがそれらを通過しないと@BindsInstanceの使用は、より良いモジュールからの種類を提供するよりも、最適化された可能性がある場合、DRダガーは、任意の引数なしのコンストラクタモデルそのものを作成します。


まず、Applicationが必要なコンポーネントがありました。したがって、モジュールを構築してコンポーネントに渡します。

コンポーネントビルダーを使用すると、という単一のオブジェクトをコンポーネントにバインドできます。これは私たちが上記のやり方に代わるものです。もはやモジュールの必要はなくなりました。私たちのコンポーネントに必要なオブジェクトをDaggerに直接渡すことができます。
インタフェース実装を提供するのは@Bindsであるため、Daggerは、意図をより明確にマークしているため、モジュールを使用した単純なアプローチよりも優れた機能を最適化できます。

@BindsInstanceを使用すると、タイプをコンポーネントに追加して、モジュールを提供する必要がなくなります。また、モジュールコンストラクタからパラメータを削除することもできます。

コンポーネントをインスタンス化するときに、どのようにしてappModule(新しいAppModule(this))からアプリケーション(this)に到達しましたか?

ダガーが明示的にコンポーネントにモジュールを追加する必要はなくなった、と我々は新しい.application(this)呼び出してその行を置き換えることができます引数なしのモジュール自体をインスタンス化することはできませんので。

+0

を書く(ビルド);'ので、どのような ' appliction(これ)は 'のですか? –

+0

'Component.Builder'インターフェースをチェックしてください! '@BindsInstance Builderアプリケーション(アプリケーションアプリケーション);' –

+0

今私は参照してください:あなたは呼び出す必要があるコンポーネントにアプリケーションをバインドするメソッドを登録します! David Medenjakさん、本当にありがとう –

0
@Component.Builder 
    interface Builder { 
     AppComponent build(); 
     @BindsInstance Builder application(Application application);  
    } 

我々は

.applicationの(この)

Applicationクラスから

アプリケーション(応用アプリケーション)

メソッドを呼び出します

アプリケーションオブジェクトをAppComponentに設定します。 appcomponet内で、アプリケーションインスタンスが利用可能になります。

daggerは必要な場所に自動的にアプリケーションインスタンスを挿入するため、以下のコードをアプリケーションモジュールから削除できます。

Application application; 
    public AppModule(Application application) { 
     this.application = application; 
    } 

    @Provides 
    Application providesApplication() { 
     return application; 
    } 

また、デフォルトのコンストラクタを使用してすべてのモジュールをインスタンス化します。

あなたはAppModuleからContextオブジェクトをしたい場合は、単にダガーは、引数なしのモジュール自体をインスタンス化することができれば、私達はちょうど `DaggerAppComponent.builder()を使用してコールド

@Module 
public class AppModule { 

    @Provides 
    Context provideContext(Application application) { 
     return application; 
    } 
} 
関連する問題