Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 多组分独立注入_Java_Android_Dependency Injection_Dagger 2 - Fatal编程技术网

Java 多组分独立注入

Java 多组分独立注入,java,android,dependency-injection,dagger-2,Java,Android,Dependency Injection,Dagger 2,我正在处理的android项目的dagger配置: 注意:我已经提供了所需的所有@Component、@Module、@提供了所需的注释 MainActivity { @Inject A a; @Inject B b; onCreate(){ ComponentX.inject(this); ComponentY.inject(this); } } ComponentX-> ModuleA ->providerA ComponentY -> Modu

我正在处理的android项目的dagger配置: 注意:我已经提供了所需的所有@Component、@Module、@提供了所需的注释

MainActivity {

@Inject A a;
@Inject B b;

 onCreate(){
    ComponentX.inject(this);
    ComponentY.inject(this);
 } 
}

ComponentX-> ModuleA ->providerA
ComponentY -> ModuleB -> providerB
正如您所看到的,这是两个完全独立的组件,除了在注入点之外,它们在任何方面都不相关

在编译过程中,我遇到以下错误:

In file A.java
error: B cannot be provided without an @Provides- or @Produces-annotated method.
MainActivity.b
[injected field of type: B b]
我是否错误地认为在使用dagger 2时可以使用多个组件,或者应用程序应该使用一个负责所有注入的大组件

谁能帮我理解我哪里出了问题

应用程序应该使用一个大的组件吗 在所有的注射中

您可以使用
子组件
。在您的情况下,组件声明如下所示:

@Subcomponent(modules=ModuleB.class)
public interface ComponentY{
    void inject(MainActivity mainActivity);
}

@Component(modules=ModuleA.class)
public interface ComponentX{
    ComponentY plus(ModuleB module);
}
ComponentY
创建:
creationcomponenty=ComponentX.plus(新模块b())

现在在
MainActivity
中,您只调用
component.inject(this)

有关子组件的更多信息,请参见(查看子图部分)和(查看子组件部分)

应用程序应该使用一个大组件吗

有点,你应该在范围内考虑。对于给定的范围,有一个组件。范围例如是
应用程序范围
片段范围
(保留),
活动范围
视图范围
。对于每个范围,都有一个给定的组件;作用域不在组件之间共享

(这本质上意味着,如果您希望在
@ApplicationScope
中有全局单例,则有一个应用程序范围的组件。如果您想要特定于活动的类,则需要为该特定活动创建一个组件,这将取决于应用程序范围的组件)

有关
@Subcomponent
注释,请参考@MyDogTom,但您也可以使用组件依赖关系来创建子范围的组件

@YScope
@Component(dependencies = ComponentX.class, modules=ModuleB.class)
public interface ComponentY extends ComponentX {
    B b();

    void inject(MainActivity mainActivity);
}

@XScope
@Component(modules=ModuleA.class)
public interface ComponentX{
    A a();
}

ComponentY componentY = DaggerComponentY.builder().componentX(componentX).build();

您不必拥有单个组件,可以通过各种方式对它们进行模块化,但您创建的每个对象或向其中注入值的对象必须由单个组件提供其所有值

重构代码的一种方法是让ComponentY依赖于ComponentX,反之亦然,例如

@Component(dependencies = ComponentX.class)
interface ComponentY {
    void inject(MainActivity activity);
}
或者,如果ComponentX和ComponentY彼此完全正交,您可以创建第三个组件,比如ComponentZ

@Component(dependencies = {ComponentX.class, ComponentY.class})
interface ComponentZ {
    void inject(MainActivity activity);
}
或者您可以重用模块,例如

@Component(modules = {ModuleA.class, ModuleB.class})
interface ComponentZ {
    void inject(MainActivity activity);
}
您决定如何准确地拆分它在很大程度上取决于代码的结构。如果组件X和Y可见,但模块不可见,则使用组件依赖项,因为它们(和模块依赖项)实际上是组件的实现细节。否则,如果模块可见,则简单地重用它们


我不会为此使用作用域,因为它们实际上是用于管理具有不同生命周期的对象,例如,与特定用户关联的对象,其生命周期是用户从登录到注销的时间,或特定请求的生命周期。如果它们的使用寿命不同,那么您正在考虑使用作用域和子组件。

1)这是否适合您?因为这是两个不同的范围。2) 通过从componentX扩展组件Y,最终讨论的是一个组件。您已经选择了继承路径,而我正在考虑组合路径(通过选择组件间依赖关系)。当然,如果添加两个自定义范围注释,它会编译,YScope是XScope的子范围。认为ActivityScope是ApplicationScope的一个子范围。在本例中,您也在谈论将其组合成一个负责注入的大组件。您没有完全处理两个独立组件的场景。有两个单独的注入我认为,在使用它之前组合最终组件比按照您的建议进行多次注入要好得多。您的
main活动
不应该知道您的依赖关系在
组件
之间是如何分布的。是否有两个或三个组件等,您可以自由更改该分布,以便在不更改
MainActivity
@MyDogTom的情况下提供更方便的测试或更方便的重用。我有点不同意组成一个“胖”组件更好。我想自由地在课堂上直接注入东西。在这两种情况下,MainActivity都没有关于组件创建的线索,只关心注入的内容。我不是说你错了,只是这是不同的视角,但我认为这是一个局限性。合成方法是我目前作为中间解决方案所做的。另一方面,根据我的理解,范围是一种不同的用法,就像你提到的那样。我想确定的是,这是否是正确的方法,单目标注入组件是由多个组件组成的(在库项目中提供)这绝对是一个好方法,是否正确的方法取决于您。同样,这取决于你的“api”是什么以及你想如何将其模块化。这绝对是一个好方法,是否正确取决于你自己。同样,这取决于您的“api”是什么以及您希望如何对其进行模块化。唯一值得考虑的是,如果您的模块提供程序方法和组件没有范围,那么您将在每次注入调用中获得一个新实例。但是,如果存储模块中创建内容的引用,并在创建后返回该引用,则可以解决此问题。不过有点长。
@Component(modules = {ModuleA.class, ModuleB.class})
interface ComponentZ {
    void inject(MainActivity activity);
}