如何使用Dagger 2将多个组件注入到同一个对象中

15

所以我有一个ApplicationComponent,用于向我的Fragment和Presenter注入单例,但我正在尝试创建一个组件,以便向与AppComponent相同的Presenter进行注入。

@Component{modules = FileManagerModule.class}
public interface FileManagerComponet
{
    public void inject(MyPresenter presenter);
}

@Component{modules = AppModule.class}
public interface AppComponent
{
    public void inject(MyPresenter presenter);
}

@Module
public class AppModule
{
    private Context appContext;
    @Provides
    @Singleton
    public SharedPreferences preferences()
    {
        return appContext.sharedPreferences();
    }
    ...
}

@Module
public class FileManagerModule
{
    private Context activityContext;
    @Provides
    public FileManager FileManager()
    {
        return new FileManager(activityContext);
    }
    ...
}

2
这个问题已经被问了多次,一个组件必须提供所有的字段,否则它将无法正常工作。您不能混合和匹配组件。例如,请在此处检查:https://dev59.com/j5nga4cB1Zd3GeqPc71K#38897722 - David Medenjak
@DavidMedenjak 那么如果AppComponent在应用程序创建时构建,并且没有活动上下文,那我该如何向FileManagerModule提供活动上下文呢? - Stampede10343
1个回答

20

对于任何无法理解这个问题的人,一个组件必须提供所有依赖关系给对象。因此在我的情况下,我必须将FileManagerComponent作为子组件,并使用.plus()与我的AppComponent一起使用,或者使其依赖于AppComponent并通过具有Context context();方法的AppComponent公开下游上下文,让依赖于它的组件可以访问它拥有的上下文。

例如:

@Singleton
@Component(modules = {NetworkModule.class, AndroidModule.class})
public interface ApplicationComponent {
    FileManagerComponent plus(FileManagerModule module);
}

@Subcomponent(modules = {FileManagerModule.class})
public interface FileManagerComponent {
    void injectMyActivity(MyFileManagingActivity activity);
}

你可以在MyFileManagingActivity中像这样使用它:

FileManagerComponent fmc = applicationComponent.plus(new FileManagerModule());
fmc.injectMyActivity(this);

或者如果您不想使用子组件,可以尝试以下代码:

@Singleton
@Component(modules = {NetworkModule.class, AndroidModule.class})
public interface ApplicationComponent {
    Context context();
    File applicationRootDirectory();
}

// Notice this is ALSO a Component
@Component(modules = {FileManagerModule.class}, dependencies = ApplicationComponent.class)
public interface FileManagerComponent {
    void inject(MyFileManagerActivity activity);
}

现在,您需要构建依赖于应用组件的组件。

FileManagerComponent fmc = DaggerFileManagerComponent.builder()
                   .applicationComponent(appComponent)
                   .fileManagerModule(new FileManagerModule())
                   .build();
fmc.inject(this);

2
如果您能在此处添加代码,那将非常好。因为子组件的官方文档和示例太难理解了。 - eC Droid
@Stampede10343:如果我的 FileManagerModule 包含另一个模块,我会怎么样?我得到了 [Dagger/SubcomponentFactoryMethodMissingModule]。我错过了什么吗? - theapache64

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接