它是如何工作的@BindsInstance dagger 2

时间:2017-02-07 04:37:34

标签: dagger-2 dagger

我最近更新了匕首2.8到2.9匕首。最新版本的文档已添加如下:

- 为组件构建器添加@BindsInstance以轻松绑定在图形外部构造的实例。

- 生产者:添加ProducerMonitor.ready (),当所有生产者的输入都可用时调用。{/ p>

-Removed @Provides(type =...)用法。请改用dagger.multibindings中的注释。 @Produces.type也已删除。

- 现在验证所有绑定方法,即使它们在特定@Component

中未使用

- @Component.dependencies无法再包含@Modules

我想知道这些新功能:

谢谢!

注意:我是匕首2的新手,但您希望能够最大限度地利用此库。

3 个答案:

答案 0 :(得分:13)

@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();

答案 1 :(得分:4)

答案 2 :(得分:1)

@BindsInstance让组件直接托管依赖项,因此生存期就是组件的生存期。这可以用来避免@Singleton范围。有关系吗避免单例作用域可帮助DaggerAppComponent访问提供程序而无需进行昂贵的DoubleCheck。因此,可以,仍然可以使用模块而不使用任何范围。但是,使用模块仍然意味着DaggerAppComponent将使用提供者工厂来注入依赖项。使用@BindsInstance,根本不需要提供者,除非通过Lazy <>或Provider <>懒惰地注入了依赖项。

任何被创建为AppComponent的依赖项(例如String常量等)都是@BindsInstance的良好候选者。请注意,这是基于Dagger 2.19的。