了解 Dagger 2 @Component.Builder 注解

问题描述 投票:0回答:3

我正在阅读this很棒的教程,它解释了

@Component.Builder
如何在Dagger 2中工作。作者做得很好,文章很直接,但仍然有一些令人困惑的地方我需要澄清:Dagger的默认实现2 看起来像这样:

组件:

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

组件实例化:

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);      
  }

}

模块:

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

我几乎明白了上面的代码是如何工作的,但这里是我不明白的部分:当我们实例化组件时,我们是如何从

appModule(new AppModule(this))
application(this)
的?

我希望问题很清楚,谢谢。

android components dagger-2
3个回答
21
投票

tl;dr 如果您不传入任何无参数构造函数模型,Dagger 会自行创建它们,并且

@BindsInstance
的使用可能比从模块提供类型得到更好的优化。


首先,您有一个需要构造

Application
的组件。因此,您构建模块并将其传递给组件。

现在,使用组件构建器,您可以将单个对象“绑定”到组件。这是我们上面所做的替代方案。不再需要模块,我们可以直接将组件中想要的对象交给 Dagger。 由于使用 @Binds
来提供接口实现,因此您通常可以假设 Dagger 可以并且将会比使用模块的简单方法更好地优化功能,因为其意图更加明确。


因此,使用

@BindsInstance

会将类型添加到我们的组件中,这样我们就不再需要模块来提供它。我们现在还可以从模块构造函数中删除参数。


当我们实例化组件时,我们是如何从 appModule(new AppModule(this)) 到 application(this) 的?

由于 Dagger 本身可以实例化无参数模块,因此不再需要显式地将模块添加到组件中,我们可以用新的
.application(this)

调用替换该行。

    


7
投票
当我们调用该方法时

申请(申请申请)

来自应用程序类

.应用程序(这个)

它将把我们的应用程序对象设置为AppComponent。因此,在 appcomponet 内部,应用程序实例可用。

因此我们可以从应用程序模块中删除以下代码,因为 dagger 会在需要的地方自动注入应用程序实例。

Application application; public AppModule(Application application) { this.application = application; } @Provides Application providesApplication() { return application; }

Dagger 还使用默认构造函数实例化所有模块。

如果您想要来自 AppModule 的 Context 对象,只需编写

@Module public class AppModule { @Provides Context provideContext(Application application) { return application; } }



0
投票
按照以下步骤操作

从导入部分删除该行
    “import com.joiibmed.Dagger2.DaggerAppComponent;”
  1. 运行应用程序,它会再次给你同样的错误。
  2. 此时转到出现导入错误的函数。并且您会收到建议
  3. “导入类” 再次运行应用程序。
© www.soinside.com 2019 - 2024. All rights reserved.