Dagger 2 构造函数注入等

Posted

技术标签:

【中文标题】Dagger 2 构造函数注入等【英文标题】:Dagger 2 Constructor Injection and more 【发布时间】:2015-10-01 18:53:43 【问题描述】:

我对 dagger2 有一些我觉得很难理解的问题。这段代码:

@Module
public class AppModule 

    private MainApplication applicationContext;

    @Inject
    public AppModule(MainApplication context)
        this.applicationContext = context;
    

    @Provides
    @Singleton
    StuffA provideStuffA()
        return new StuffA();
    

    @Provides
    @Singleton
    StuffB provideStuffB(StuffA)
         return new StuffB(stuffA);
    

在应用类中:

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

我的第一个问题是:

如果我想将 Module 拆分为 2,ModuleA 中的 provideStuffA 和 ModuleB 中的 provideStuffB,考虑到 B 依赖于 A,我该如何实现。

第二个问题:

我有一个在应用程序类中使用的对象,它来自应用程序类,我从活动中调用注入。那么我如何在应用程序 class= 中访问该对象?我应该在上面的 Dagger 构建内容之后在我的 applicationClass 上调用 inject 吗?

最后一个问题

假设我有两个具有不同依赖关系的模块,我需要在同一个活动中使用它们。让一个组件和不同模块注入同一活动的正确方法是什么。

附言。如果这真的是基本的东西,我很抱歉,但我发现文档很差,也缺乏示例。提前致谢

【问题讨论】:

【参考方案1】:

回答 1

您只需将它们拆分为两个单独的模块。 Dagger 将构建图形,当在某个时候调用 provideStuffB() 时,它将用 StuffA 注入它。顺便说一句,我认为provide 方法中存在小的语法错误,应该是(stuffA 参数丢失):

@Provides
@Singleton
StuffB provideStuffB(StuffA stuffA)
     return new StuffB(stuffA);

答案 2

是的,这是通常的方式。在您创建图形之后(在onCreate() 中),您注入this(应用程序)。请注意,在使用这种方法进行单元测试时有一个微妙的警告 - 甚至在调用 setUp() 方法之前就会创建 Application 对象,因此您将无法设置/交换您的测试组件(您最终会始终使用您的默认组件)。解决方案是使用图的惰性初始化,即当第一个活动(或服务,或BroadcastReceiver 等)调用getApplication().getInjector(this) 时,您必须在那时创建图。

答案 3

您通常有一个 top Component,其中包含所有模块和子组件。它(必须)能够注入所有活动。事实上,顶部组件用于生成图形。以下是真实应用的示例:

@Component(modules = IzgubenoDaggerModule.class,
                        AcraDaggerModule.class,
                        AppInfoDaggerModule.class,
                        SessionDaggerModule.class,
                        ComponentManagerDaggerModule.class,
                        NetworkInfoProviderDaggerModule.class,
                        DeviceInfoProviderDaggerModule.class,
                        KhRestExchangeManagerDaggerModule.class
                     )
@Singleton
public interface IzgubenoDaggerComponent extends GgLibDaggerComponent 
    void inject(IzgubenoApplication app);
    void inject(Act_Main act);
    void inject(Act_ContactDetails act);
    void inject(Act_MyPets act);
    void inject(Act_PetEdit act);
    void inject(Act_PetManage act);
    void inject(Act_PetPics act);
    //...
    GgLibDaggerComponent newGgLibDaggerComponent(HttpsDaggerModule httpsMod,
                                             KhRestDaggerModule khrestMod,
                                             AppInfoDaggerModule appInfoMod,
                                             GgServerDaggerModule ggServMod,
                                             GgClientDaggerModule ggClientMod);
    //...

【讨论】:

以上是关于Dagger 2 构造函数注入等的主要内容,如果未能解决你的问题,请参考以下文章

Android--Dagger2入门

Java依赖注入库框架 Dagger的源码分析

在Gson反序列化期间使用Dagger进行依赖注入

Dagger 2 错误:依赖“不能在没有 @Inject 构造函数的情况下提供”,而它实际上是用 @Inject 注释的

Dagger2下的ViewModel

Kotlin + Dagger2:不能在没有 @Inject 构造函数或 @Provides- 或 @Produces-annotated 方法的情况下提供