Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
477 views
in Technique[技术] by (71.8m points)

dependency injection - Component which dependent from other components with different scopes (component hierarchies with different scopes)

I have complex multi-tier architecture in my Android project.

Currently i want to use the following structure of the DI components and modules:

[Data Layer]
    @DataScope //scope is used for caching (Singleton) some Data Layer entities for whole application
    - DataComponent //exposes just interfaces which should be used on the BL Layer
        //Modules exposes entities for internal (Data Layer) injections and entities which exposed by DataComponent for BL Layer
        * DataModule1
        * DataModule2
        * DataModule3

[Business Logic Layer] (also has component dependency on DataComponent)
    @BlScope //scope is used for caching (Singleton) some BL Layer entities for whole application
    - BlComponent //exposes just interfaces which should be used on the Service Layer & Presentation Layer
        //Modules exposes entities for internal (BL Layer) injections and entities which exposed by BLComponent for the Service Layer & Presentation Layer
        * BlModule1
        * BlModule2

[Service Layer] (also has component dependency on BlComponent) - this layer has Android specific entities (Android Service, ContentProvider) not related to the Presentation Layer
    @ServiceScope //scope is used for caching (Singleton) some Service Layer entities for whole application
    - ServiceComponent //exposes just interfaces which should be used on the Presentation Layer
        * ServiceModule //Module exposes entities for internal (Service Layer) injections and entities which exposed by ServiceComponent for the Presentation Layer

[Presentation Layer] (also has component dependency on: ServiceComponent, BlComponent)
    @PresentationScope //scope is used for caching (Singleton) some Presentation Layer entities for whole application
    - PresentationComponent //exposes just interfaces which should be used on the current layer
        * PresentationModule //Module exposes entities injections on the current layer

The ServiceComponent & BlComponent don't expose the similar interfaces.

To build the main graph i use the following code:

DataComponent dataComponent = DaggerDataComponent.builder().<addModules>.build();
BlComponent dataComponent = DaggerBlComponent.builder().<addModules>.dataComponent(dataComponent).build();
ServiceComponent serviceComponent = DaggerServiceComponent.builder().<addModule>.blComponent(blComponent).build();
PresentationComponent presentationComponent = DaggerPresentationComponent.builder().<addModule>.blComponent(blComponent).serviceComponent(serviceComponent).build();

In the PresentationLayer i use only "presentationComponent" to provide required dependencies from ServiceComponent/Layer and BLComponent/Layer.

Currently scenario above doesn't work, because PresentationComponent depends on the 2 scoped components with the error

"...depends on more than one scoped component:..."

Though it allows to use one scoped component with many non-scoped components. This architecture is directed to restrict to use internal layer entities on the upper layers and in the same time to have independent tests (unit & instrumentation) on each layer/module.

Could anybody help me to understand is it bug or desirable behavior of the Dagger processor? (and why?) Issue on the Dagger2 repo: https://github.com/google/dagger/issues/747#issuecomment-303526785

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is no longer an issue in later version of Dagger 2 as per the fix here

On older versions of Dagger 2, it is possible to work around the problem by declaring components that depend on supertypes of Dagger components as per the GitHub example here:

interface AppComponent {
  App app();
}

@Component(dependencies = AppComponent.class)
interface RequestComponent { ... }

@Component
interface EnglishAppComponent extends AppComponent {}

@Component
interface SpanishAppComponent extends AppComponent {}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...