其他分享
首页 > 其他分享> > Android | Dagger 2.根据条件将不同的子类注入Fragment

Android | Dagger 2.根据条件将不同的子类注入Fragment

作者:互联网

我正在使用MVP和Dagger 2 DI.我有一个片段,我在一些活动中重用.作为片段的属性,我有一个接口类型作为片段的属性,比如MVPPresenter.根据片段的使用活动,我需要向其中注入不同的演示者(每个演示者都是MVPPresenter的实现).所以我需要一种方法将MVPPresenter的每个实现注入到我需要的片段中.

目前,我有一个可怕的解决方案,这是有效的,但它是完全错误的,并创建了从未使用过的不必要的对象.这是代码:

public class MyFragment {

...

@Inject
public void setPresenter(@NonNull ProfilePresenter presenter) {
    if (mAdapter instanceof ProfileAdapter) {
        this.presenter = presenter;
    }
}

@Inject
public void setPresenter(@NonNull ContactsPresenter presenter) {
    if (mAdapter instanceof ContactsAdapter) {
        this.presenter = presenter;
    }
}
...
}

这是我的模块:

@Module
class PresentersModule {

@Provides
@Singleton
ProfilePresenter ProfilePresenter() {
    return new ProfilePresenter();
}

@Provides
@Singleton
ContactsPresenter ContactsPresenter() {
    return new ContactsPresenter();
}
}

你看,根据适配器类型,我指定演示者,或不.我知道这是愚蠢的.问题是Dagger需要精确的类型来指定注入和接口类型不能工作.
处理此类案件的正确方法是什么?

解决方法:

通过查看你给mvp-presenters的名字,可以得出结论,他们的互补mvp视图应该分开并以不同的片段实现.

但是如果你希望保持原样,只在你的片段中声明了单个setPresenter方法,那么处理问题的最简单方法可能是引入具有补充模块的独立组件,以提供理想的演示者实现.

要使此解决方案起作用,您需要调整片段以包含具有MVPPresenter类型作为参数的setPresenter方法的单个声明:

@Inject
public void setPresenter(@NonNull MVPPresenter presenter) {
    this.presenter = presenter;
}

之后,您需要提供公开inject(…)方法的组件并声明适当模块的使用.由于这些依赖图将依赖于主要组件实例,因此它们应该获得自己的范围(与活动或片段相关联,具体取决于实际持有图形对象的类).

例如,如果您使用DiComponent为所有依赖项提供通过@Singleton注释定义的范围,则需要声明@MyFragmentScope注释并提供依赖于上述DiComponent的组件,以声明可注入的演示者:

import javax.inject.Scope;

@Scope
public @interface MyFragmentScope {
}

您的依赖组件看起来像:

@MyFragmentScope
@Component(dependencies = DiComponent.class, modules = ProfileModule.class)
public interface ProfileComponent {
    void inject(MyFragment fragment);
}

与补充模块:

@Module
public class ProfileModule {
    @Provides
    @MyFragmentScope
    MVPPresenter providesProfilePresenter() {
        return new ProfilePresenter();
    }
}

注意:返回类型是MVPPresenter,而不是具体实现.

同样,您需要为ContactsPresenter创建ContactsComponent和ContactsModule.

最终,您应该使用适当的组件实例来执行注入.现在而不是使用

diComponent.inject(myFragment)

你应该使用能提供理想依赖性的组件.

此时,您实际上会有一个开关,用于定义应使用哪个演示者.
在ProfilePresenter注入的情况下,您需要使用:

DaggerProfileComponent.builder()
        .diComponent(diComponent)
        .build()
        .inject(myFragment);

或者在ContactsPresenter注入的情况下,您需要使用:

DaggerContactsComponent.builder()
        .diComponent(diComponent)
        .build()
        .inject(myFragment);

对于像活动这样的应用程序的较小部分使用单独的组件是相当普遍的做法.可以将这些组件声明为常规依赖组件或子组件(请参阅@Subcomponent文档以供参考).从Dagger 2.7开始,有一种通过@ Module.subcomponents声明子组件的新方法.由于这个事实,有机会将AppComponent与活动子组件分离.您可以参考frogermcs的sample GitHub repository作为参考.他在这个主题上也有很好的补充blog post.

标签:android,android-fragments,dagger-2,android-mvp
来源: https://codeday.me/bug/20190828/1753239.html