使用Dagger组件依赖项时如何避免循环依赖项

时间:2020-06-10 01:14:39

标签: java dagger-2

如何避免Dagger组件之间的循环依赖

假设我有两个接口的库:EngineCar

package com.library;
interface Engine {}
package com.library;
interface Car {}

该库还包含一个实现:MyCar,但重要的是,不是一个Engine的实现:

package com.library;
class MyCar implements Car {
    public MyCar(Engine engine) {}
}

我有一个依赖于此库的应用程序。该应用程序包含Engine

的实现
package com.application;
class HybridEngine implements Engine {
    public HybridEngine(...) {} 
}

我现在想使用Dagger来满足这些依赖性。库和应用程序都有一个Dagger模块和Dagger组件。我将应用程序组件设置为依赖于库组件:

package com.library;
@Module
public class LibraryModule {
    @Provides
    @LibraryScope
    Car provideCar(Engine engine) {
        return new MyCar(engine);
    }
}
package com.library;
@LibraryScope
@Component(modules = {LibraryModule.class})
public interface LibraryComponent {
}
package com.application;
@Module
public class ApplicationModule {
    @Provides
    @ApplicationScope
    Engine provideEngine() {
        return new HybridEngine();
    }
}
package com.application;
@ApplicationScope
@Component(
        modules = {ApplicationModule.class},
        dependencies = {LibraryComponent.class})
public interface ApplicationComponent { }

然后在我的应用程序中创建这些组件:

onCreate() {
    LibraryComponent libraryComponent = DaggerLibraryComponent.builder()
            .build();

    ApplicationComponent appComponent = DaggerApplicationComponent.builder()
            .libraryComponent(libraryComponent)
            .build();
}

这会产生问题。为了向LibraryComponent提供Engine(以便满足MyCar的依赖性),我必须在@BindsInstance内使用LibraryComponent

package com.library;
@LibraryScope
@Component(modules = {LibraryModule.class})
public interface LibraryComponent {

    Car getCar();

    @Component.Builder
    interface Builder {

        @BindsInstance
        LibraryComponent.Builder bindEngine(Engine engine);

        LibraryComponent build();
    }
}

然后创建的组件如下所示:

public void onCreate() {
    Engine engine = ...
    LibraryComponent libraryComponent = DaggerLibraryComponent.builder()
            .bindEngine(engine)
            .build();

    ApplicationComponent appComponent = DaggerApplicationComponent.builder()
            .libraryComponent(libraryComponent)
            .build();
}

但是我不知道如何访问Engine。我可以在对象图的外部创建一个。但是我需要由对象图创建的引擎,以便我可以提供依赖项(未显示)。我该怎么办?

换句话说,如果父组件需要由父组件提供其自己的依赖关系,那么该父组件又该如何向该依赖组件提供对象呢?

您稍后可以感谢我没有使用Thermosiphon示例


更新

在接受@ Denvercoder9的建议之后,我删除了@BindsInstance和LibraryComponent.Builder。然后,我将@Inject添加到HybridEngineConstructor

package com.application;
class HybridEngine implements Engine {
    @Inject public HybridEngine() { }
}

然后我添加了@Named批注:

package com.application;

@Module
public class ApplicationModule {
    @Named("HybridEngine")
    @Provides
    @ApplicationScope
    Engine provideEngine() {
        return new HybridEngine();
    }
package com.library;
@Module
public class LibraryModule {
    @Provides
    @LibraryScope
    Car provideCar(@Named("HybridEngine") Engine engine) {
        return new MyCar(engine); 
   }
}

但是我现在遇到构建错误:

error: [Dagger/MissingBinding] @javax.inject.Named("HybridEngine") com.library.Engine cannot be provided without an @Provides-annotated method.
public interface LibraryComponent {
       ^

0 个答案:

没有答案