Dagger 2子组件与组件依赖关系

Bra*_*ell 121 dagger dagger-2

Dagger 1的plus()方法是我以前在应用程序中经常使用的方法,所以我理解你可能希望有一个子组件可以完全访问父图形绑定的情况.

在什么情况下使用组件依赖项而不是子组件依赖项是有益的?为什么?

Pra*_*pta 210

组件依赖关系 - 如果要保持两个组件独立,请使用此选项.

子组件 - 当您想要保持两个组件耦合时使用此组件.


我将使用下面的示例来解释组件依赖项子组件.值得注意的一些例子是:

  • SomeClassA1可以创建没有任何依赖.通过该方法ModuleA提供和实例.SomeClassA1provideSomeClassA1()
  • SomeClassB1不能没有SomeClassA1.只有将一个实例作为参数传递给方法时ModuleB才能提供实例.SomeClassB1SomeClassA1provideSomeClassB1()
@Module
public class ModuleA {
    @Provides
    public SomeClassA1 provideSomeClassA1() {
        return new SomeClassA1();
    }
}

@Module
public class ModuleB {
    @Provides
    public SomeClassB1 provideSomeClassB1(SomeClassA1 someClassA1) {
        return new SomeClassB1(someClassA1);
    }
}

public class SomeClassA1 {
    public SomeClassA1() {}
}

public class SomeClassB1 {
    private SomeClassA1 someClassA1;

    public SomeClassB1(SomeClassA1 someClassA1) {
        this.someClassA1 = someClassA1;
    }
}
Run Code Online (Sandbox Code Playgroud)

每当组件/子组件声明初始化时,Dagger将负责将SomeClassA1作为参数的实例传递给provideSomeClassB1()方法.我们需要指导Dagger如何实现依赖.这可以通过使用Component依赖项Subcomponent来完成.ModuleBModuleB

组件依赖

请注意下面的Component依赖示例中的以下几点:

  • ComponentB必须通过注释dependencies方法定义依赖关系@Component.
  • ComponentA不需要申报ModuleB.这使两个组件保持独立.
public class ComponentDependency {
    @Component(modules = ModuleA.class)
    public interface ComponentA {
        SomeClassA1 someClassA1();
    }

    @Component(modules = ModuleB.class, dependencies = ComponentA.class)
    public interface ComponentB {
        SomeClassB1 someClassB1();
    }

    public static void main(String[] args) {
        ModuleA moduleA = new ModuleA();
        ComponentA componentA = DaggerComponentDependency_ComponentA.builder()
                .moduleA(moduleA)
                .build();

        ModuleB moduleB = new ModuleB();
        ComponentB componentB = DaggerComponentDependency_ComponentB.builder()
                .moduleB(moduleB)
                .componentA(componentA)
                .build();
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意SubComponent示例中的以下几点:

  • 由于ComponentB尚未定义依赖性ModuleA,因此无法独立生存.它依赖于将提供的组件ModuleA.因此它有一个@Subcomponent注释.
  • ComponentAModuleB通过接口方法声明componentB().这使得两个组件耦合.实际上,ComponentB只能通过初始化ComponentA.
public class SubComponent {
    @Component(modules = ModuleA.class)
    public interface ComponentA {
        ComponentB componentB(ModuleB moduleB);
    }

    @Subcomponent(modules = ModuleB.class)
    public interface ComponentB {
        SomeClassB1 someClassB1();
    }

    public static void main(String[] args) {
        ModuleA moduleA = new ModuleA();
        ComponentA componentA = DaggerSubComponent_ComponentA.builder()
                .moduleA(moduleA)
                .build();

        ModuleB moduleB = new ModuleB();
        ComponentB componentB = componentA.componentB(moduleB);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我有一个子组件设置,不会将模块B添加到ComponentA,这意味着componentA构建器不需要moduleB.这看起来像我预期允许在应用程序启动时创建ComponentA然后实例化m的方式 (4认同)
  • @MikeN - 你能否强调如何摆脱ComponentA上的ModuleB?如果我在ComponentA和ComponentB上提供不同的范围,我只能在ComponentA上摆脱ModuleB. (2认同)
  • "`SomeClassB1`依赖于`SomeClassA1`."ComponentA"必须明确定义依赖." ==>你的意思是"`ComponentB`必须明确定义依赖"? (2认同)

Eug*_*ene 45

根据文件:

Component Dependency通过组件依赖性,您只能访问作为提供方法公开的绑定,即您只能访问在父级中声明的类型Component.

SubComponent在声明它时,它允许您从其父级访问整个绑定图,即您可以访问其Modules中声明的所有对象.

比方说,你有一个ApplicationComponent包含所有Android相关的东西(LocationService,Resources,SharedPreference等).您还希望拥有DataComponent管理持久性的地方以及WebService处理API.你唯一缺少的DataComponentApplication Context它所在的东西ApplicationComponent.得到一个最简单的方法ContextDataComponent将是对的依赖ApplicationComponent.您需要确保已Context明确声明,ApplicationComponent因为您只能访问声明的内容.在这种情况下,没有手动工作,这意味着您不需要Submodules在父项中指定Component并将子模块显式添加到父模块,如:

MySubcomponent mySubcomponent = myComponent.plus(new ChildGraphModule("child!")); // No need!
Run Code Online (Sandbox Code Playgroud)

现在考虑要注入这种情况下,WebServiceDataComponentLocationServiceApplicationComponent到您的Fragment使用结合@Submodule plus上述特征.这里的很酷的事情是,你结合组分(ApplicationComponent)并没有需要公开WebService,也不LocationService是因为你有机会获得整个图形的时候了.

  • 如果我理解正确,没有名为`@Submodule` 的接口。这是一个错字吗? (2认同)

0xA*_*iHn 12

以下是带有屏幕截图的代码示例,以便更好地理解Component和SubComponent:

零件: 在此输入图像描述

  1. AppComponent包含两个声明.
  2. AppComponent初始化为App类.
  3. HomeActivityComponent依赖于AppComponent.
  4. 在HomeActivity初始化DaggerHomeActivityComponent时,我将AppComponent对象作为一个组合.

子:

在此输入图像描述

  1. AppComponent包含SubComponent或SubComponents.
  2. AppComponent初始化为App类.
  3. SubComponent不知道他的ParentComponent.这只是通过包含Module提供自己的依赖项.
  4. 在HomeActivity中,我使用其父组件注入SubComponent.

图画图: 在此输入图像描述

来源:链接

  • 如果子组件包含 AppComponent,该图不是更有意义吗? (3认同)