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

时间:2015-06-22 05:22:42

标签: android android-fragments dagger-2

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

  1. MVP Presenters that Survive Configuration Changes Part-2Github repo):

    • 为每个片段使用唯一的自定义范围,例如No@Hello1Scope分别为@Hello2ScopeHello1Fragment
  2. Tasting Dagger 2 on Android

    • 对所有片段使用单个自定义范围,例如Hello2Fragment
  3. 根据我的理解,似乎在方法2中,可以定义一个可用于所有片段的单一范围(即@PerFragment)。实际上(如果我错了,请纠正我),看起来自定义范围的名称是无关紧要的,并且它只是创建子组件的位置(即在应用程序,活动或片段中)的事项。

    是否有用于为每个片段定义唯一范围的用例,例如情况1?

2 个答案:

答案 0 :(得分:78)

在阅读了@vaughandroid和What determines the lifecycle of a component (object graph) in Dagger 2?的答案后,我认为我理解自定义范围足以回答我自己的问题。

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

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

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

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

  • 至少 2个注释(@Singleton@SubSingleton)和
  • 最多 n + 1 注释(@Singleton@SubSingleton1,... {{1} })。

实施例

<强>应用

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

答案 1 :(得分:17)

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

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

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

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

从快速浏览“MVP演示者...”教程,我不清楚作者的意图是什么,有独立的范围。由于名字只是一次性的,我不会读太多内容。