web-dev-qa-db-ja.com

@BindsInstanceダガー2の仕組み

最近、ダガー2.8から2.9ダガーにアップデートしました。前回のリリースのドキュメントが次のように追加されました。

-コンポーネントビルダーがグラフの外部で構築されたインスタンスを簡単にバインドできるように_@BindsInstance_を追加しました。

-プロデューサー:ProducerMonitor.ready ()が追加されました。これは、プロデューサーの入力がすべて利用可能になったときに呼び出されます。

-削除@Provides(type =...)の使用法。代わりに_dagger.multibindings_の注釈を使用してください。 _@Produces.type_も削除されました。

-特定の_@Component_で使用されていない場合でも、すべてのバインディングメソッドが検証されるようになりました。

-_@Component.dependencies_に_@Modules_を含めることはできなくなりました。

これらの新機能について知りたい:

ありがとうございました!!

注:私は短剣2を初めて使用しますが、このライブラリを最大限に活用できるようにしたいと考えています。

10
Juanes30

@bindsInstanceは、モジュールからコンストラクターを削除し、コンポーネントを取得するモジュールをチェーンするために使用されます。

@BindsInstanceなし

@Module
public class AppModule {

    private final Application application;

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

    @Provides
    @Singleton
    Application provideApplication() {
        return  application;
    }

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

これらのモジュール(ToastMakerModule、およびSensorControllerModule)は、学習目的であり、コンテキストを取得してインスタンス化します。実際の例では実用的でない場合があります

public class ToastMaker {

    private Application application;

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

    public void showToast(String message) {
        Toast.makeText(application, message, Toast.LENGTH_SHORT).show();
    }
}

    @Module
    public class ToastMakerModule {

        @Singleton
        @Provides
        ToastMaker provideToastMaker(Application application) {
            return  new ToastMaker(application);

        }
   }

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

    // DaggerAppComponent.build() returns this Builder interface

    @Component.Builder
    interface Builder {
        AppComponent build();

        Builder appModule(AppModule appModule);

        Builder sensorControllerModule(SensorControllerModule sensorControllerModule);

        Builder toastMakerModule(ToastMakerModule toastMakerModule);
    }

}

このようなコンポーネントを構築する

 appComponent = DaggerAppComponent
                .builder()
                .appModule(new AppModule(this))
                .sensorControllerModule(new SensorControllerModule())
                .toastMakerModule(new ToastMakerModule())
                .build();

@BindsInstance

@Module
public class AppModule {

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

成分

@Singleton
@Component(modules = {AppModule.class, ToastMakerModule.class, SensorControllerModule.class})

public interface AppComponent {
    void inject(MainActivity mainActivity);

    @Component.Builder
    interface Builder {

        AppComponent build();


        // @BindsInstance replaces Builder appModule(AppModule appModule)
        // And removes Constructor with Application AppModule(Application)

        @BindsInstance
        Builder application(Application application);
    }
}

そして、このようなコンポーネントを構築します

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

@BindsInstanceはユーザーガイドに記載されています: https://google.github.io/dagger/users-guide.html#binding-instances

4
Thomas Broyer

@BindsInstanceを使用すると、コンポーネントが依存関係を直接ホストできるため、有効期間はコンポーネントの有効期間になります。これは、@Singletonスコープを回避するために使用できます。それも重要ですか?シングルトンスコープを回避すると、コストのかかるDoubleCheckなしでプロバイダーにDaggerAppComponentアクセスできます。したがって、はい、まだモジュールを使用して、スコープを使用しないことは可能です。ただし、モジュールを使用することは、DaggerAppComponentがプロバイダーファクトリを使用して依存関係を注入することを意味します。 @BindsInstanceを使用すると、依存関係がLazy<>またはProvider<>を介して遅延注入されない限り、プロバイダーはまったく必要ありません。

AppComponentと呼ばれる依存関係(文字列定数など)が作成されている場合、@BindsInstanceの候補として最適です。これはDagger 2.19。に基づいていることに注意してください。

1
Vairavan