@Subcomponent可以是父@Component的子接口吗?

时间:2015-12-11 08:43:22

标签: dagger-2

有没有办法让@Subcomponent接口扩展其父@Component接口? Dagger 2是否故意不允许这样做?

我已成功创建了一个子组件,可以注入其父组件可以注入的任何内容,前提是我给它提供了这样做的方法:

@Singleton @Component(modules = ParentModule.class)
public interface ParentComponent {
    void inject(SomeObject object);
    ChildComponent plus(ChildModule module);
}

@ChildScope @Subcomponent(modules = ChildModule.class)
public interface ChildComponent {
    void inject(SomeObject object);
    void inject(SomeOtherObject object);
}

但是,子组件接口与父组件接口没有继承关系。我试图让它扩展父接口,但这不会编译:

@ChildScope @Subcomponent(modules = ChildModule.class)
public interface ChildComponent extends ParentComponent {
    //void inject(SomeObject object);
    void inject(SomeOtherObject object);
}

据我所知,错误信息无法解释原因:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project dagger-test: Compilation failure -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project dagger-test: Compilation failure
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:213)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:320)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
Caused by: org.apache.maven.plugin.compiler.CompilationFailureException: Compilation failure
    at org.apache.maven.plugin.compiler.AbstractCompilerMojo.execute(AbstractCompilerMojo.java:862)
    at org.apache.maven.plugin.compiler.CompilerMojo.execute(CompilerMojo.java:129)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
    ... 19 more
[ERROR] 
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException

1 个答案:

答案 0 :(得分:1)

我似乎找到了一个解决方案。 @Component@Subcomponent接口之间不能有直接的继承关系,但它们可以都扩展接口。而且注入方法可以在那些超级接口中:

public interface ParentInjector {
    void inject(Injectable obj);
}

public interface ChildInjector extends ParentInjector {
    void inject(Injectable2 obj);
}

@Singleton @Component(modules = ParentModule.class)
public interface ParentComponent extends ParentInjector {
    ChildComponent childComponent();
}

@ChildScope @Subcomponent(modules = ChildModule.class)
public interface ChildComponent extends ChildInjector {}

InjectableInjectable2没有继承关系:

public class Injectable {
    @Inject @Named("foo") String mFoo;
}

public class Injectable2 {
    @Inject @Named("foo") String mFoo;
    @Inject @Named("bar") String mBar;
}