Multi-layer / libraries architecture with dagger2:

2019-09-16 01:40发布

问题:

I'm using dagger 2 in a multi-layered, multi-library Android SDK project.

I'm developing many different libraries on different layers (data, business logic, presentation etc...) and using dagger to glue them together.

My most important requirement is that each library of the architecture should be usable stand-alone (with its dependent components) and that a developer should decide to build on top on any layer he wants:

for example:

  • rewrite all the presentation layer using everything below
  • replace any piece of the stack at will to enhance or change the behavior

For now I've created for each library a Dagger Component with a custom scope but sometimes I've a component that depends on 2-3 other components and Dagger complain that only 1 dependency component should be scoped. (Es. Domain layer using a service component to obtain data from a company service and a sensor component to obtain device sensor data / connectivity or whatever).

I can't get rid of scopes because I need those component to be scoped / singleton.

My current workaround is to pass the dependency component to the module constructor, but this look like a workaround and I would like to know what's the right way to approach this kind of requirement with Dagger 2.

The complexity is also not scaling very well and replacing a piece in the middle require to extend one of the module replacing the implementation, which is not user friendly at all.

I've read about subcomponents but looks like those can't be used stand-alone unless you write a component for each, they also declare modules for the actual implementation so they can't be just replaced with some other implementation.

Can someone share their architecture with dagger or elaborate on these concepts with the focus of a library project to be used by other developers to assemble parts and reuse components?

(this question has been asked initially on the dagger2 issue tracker but was closed pointing me to stack overflow -- using only module is also not suitable cause these require the user of the library to know which module to assemble and how and I have no way of setting up modules dependencies that do not force a specific implementation)

回答1:

I'm sorry but I don't think this idea will work because the requirements are a little bit contradictory.

Namely:

I can't provide modules only and not components (as recommended in the thread on the Dagger 2 issue tracker)

and

My most important requirement is that each library of the architecture should be usable stand-alone (with its dependent components) and that a developer should decide to build on top on any layer he (or she) wants

will be extremely difficult to engineer together. Dagger 2 uses static code generation at compile time. Components need to know about their sub-components or, alternatively, dependent components need to know about their parents. To have a turnkey Dagger 2 solution where all the consumer does is call inject from a component, you will need to setup the object graph at least partially. This is going to make it difficult to achieve the modularity you require.

Hence, I think the advice on the issue tracker thread (provide modules only and let the consumer set up Components) is the correct solution. You can use your own scope annotations and/or the JSR-330 @Singleton etc. annotations to provide hints to how the consumer of your library should set up their object graph.

Lastly, Amir Ziarati recently posted an example of an Android project with multiple modules using Dagger 2. I hope it helps, the link is here