Dagger 2每个片段的自定义范围(或活动等...)

bco*_*rso 35 android android-fragments dagger-2

我看了几篇不同的文章,似乎提出了在Dagger 2中进行自定义范围的两种不同方式:

  1. 存活配置改变第2部分的MVP演示者(Github repo):

    • 采用独特的定制范围的每个片段,例如@Hello1Scope@Hello2ScopeHello1FragmentHello2Fragment分别
  2. 在Android上品尝Dagger 2:

    • 对所有片段使用单个自定义范围,例如@PerFragment.

根据我的理解,似乎在方法2中,定义一个可用于所有片段(即@PerFragment)的单一范围应该是可以的.事实上(如果我错了请纠正我),似乎自定义范围的名称是无关紧要的,并且它只是创建子组件(即在应用程序,活动或片段中)的重要部分.

是否有任何用例来定义每个片段的唯一范围,例如在案例1中?

bco*_*rso 83

在阅读了@vaughandroid的答案之后,什么决定了Dagger 2中组件(对象图)的生命周期?我想我理解自定义范围足以回答我自己的问题.

首先,在处理dagger2中的组件,模块和作用域注释时,这里有一些规则.

  • 组件 必须具有(单个)范围注释(例如@Singleton@CustomScope).
  • 模块 具有一个范围的注释.
  • 模块方法 可以具有其相匹配的(单个)范围元器件或无范围,其中:
    • Scoped:表示为组件的每个实例创建单个实例.
    • Unscoped:表示每次inject()或提供者调用都会创建一个新实例
    • 注意: Dagger2仅为@Singleton根组件(及其模块)保留.子组件必须使用自定义范围,但该范围的功能与此完全相同@Singleton.

现在,回答这个问题:我想说的是为每个概念上不同的范围创建一个新的命名范围.例如,创建一个@PerActivity,@PerFragment@PerView注释,指示应该实例化组件的位置,从而指示其生命周期.

注意:这是两个极端之间的妥协.考虑根组件和n个子组件的情况:

  • 至少 2个注释(@Singleton@SubSingleton),和
  • 最多 N + 1页的注释(@Singleton,@SubSingleton1,...@SubSingletonN).

例:

应用:

/** AppComponent.java **/ 
@Singleton
@Component( modules = AppModule.class )
public interface AppComponent{
    void inject(MainActivity mainActivity);
}

/** AppModule.java **/
@Module
public class AppModule{
    private App app;

    public AppModule(App app){
        this.app = app;
    }

    // For singleton objects, annotate with same scope as component, i.e. @Singleton
    @Provides @Singleton public App provideApp() { return app; }
    @Provides @Singleton public EventBus provideBus() { return EventBus.getDefault(); }
}
Run Code Online (Sandbox Code Playgroud)

分段:

/** Fragment1Component.java **/
@PerFragment
@Component( modules = {Fragment1Module.class}, dependencies = {AppComponent.class} )
public interface Fragment1Component {
    void inject(Fragment1 fragment1);
}

/** Fragment1Module.java **/ 
@Module
public class Fragment1Module {
    // For singleton objects, annotate with same scope as component, i.e. @PerFragment
    @Provides @PerFragment public Fragment1Presenter providePresenter(){
        return new Fragment1Presenter();
    }
}

/** PerFragment.java **/ 
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface PerFragment {}
Run Code Online (Sandbox Code Playgroud)


vau*_*oid 18

你的理解是正确的.命名范围允许您传达意图,但它们都以相同的方式工作.

  • 对于作用域提供者方法,每个Component实例将创建所提供对象的1个实例.
  • 对于未作用域的提供者方法,每个Component实例将在需要注入时创建所提供对象的新实例.

但是,Component实例的生命周期非常重要.同一组件的2个不同实例将提供不同的对象实例,甚至是范围的实例.

范围名称应指示所提供对象的生命周期(与Component实例的生命周期匹配),因此@PerFragment对我来说更有意义.

通过快速浏览"MVP演示者......"教程,我不清楚作者的意图是什么,具有单独的范围.由于名字只是一次性的,我不会读太多.