google/dagger

Feature Request: Dynamic Module - Component match

yayaa opened this issue · 2 comments

yayaa commented

Current version of Dagger supports only static declaration of modules over component. This blocks us to build the graph in a more dynamic way.

I would like to have a way to get modules dynamically mapped to the components so that I can add and remove any module depending on some different build specifications.

This would be super useful for especially Android BuildTypes or/and with new InstantApp feature, we could have same level modules included into some component according to their gradle modules are built or not.


Proposal 1
Having a new type of Component as DynamicComponent with a single dynamicKey annotation to match with its modules. Such as;

@WhateverScope
@DynamicComponent(key = arrayOf("Sample1", "Sample2"))
abstract class SampleComponent 

@WhateverScope
@DynamicModule(key = "Sample1")
object Sample1Module

@WhateverScope
@DynamicModule(key = "Sample2")
object Sample2Module

These could be used to map these modules into given component, in the end, it should end up similar as following;

@WhateverScope
@Component(modules = arrayOf(Sample1Module::class, Sample2Module::class))
abstract class SampleComponent 

@WhateverScope
@Module
object Sample1Module

@WhateverScope
@Module
object Sample2Module

Proposal 2
Even more :) Having both static and dynamic module declarations in the same time such as;

@WhateverScope
@Component(dynamicModuleKey = arrayOf("Sample1", "Sample2"),
           modules = arrayOf(Sample3Module::class))
abstract class SampleComponent 

@WhateverScope
@Module(dynamicModuleKey = "Sample1")
object Sample1Module

@WhateverScope
@Module
object Sample3Module

This would also prevent creating new annotations but re-use existing ones, and make it possible both static and dynamic module addition in the same time.


Requirements

  • Dynamic Key is a mapping reference for Component. Multiple Module can have the same dynamic key to map themselves to the component.
  • Components might have dynamic key defined but this shouldn't mean that there must be a corresponding module with given key.
  • Components might have more than one dynamic key to map different modules to itself.

This defeats almost all of the benefits of Dagger 2. Dagger 1 did this - if you'd like those features and are ok without the latest Dagger 2 features you could always use that.

What it sounds like you're saying though is that you'd like to define interfaces that expose certain bindings and add them into the graph. Does @Component(dependencies = ...) work for you? There's no requirement for the dependencies to be components themselves, and you can use polymorphism there.

yayaa commented

Well, I am not really sure about it. All I ask is actually make this static implementation more generic, so that we could use for our purposes as well.

Right now, Android module looks like hard coded to achieve this behaviour. To let developers to collect their modules by ContributesAndroidInjector annotation.

This would allow us to generate components without being aware of their modules, so that we can provide the dagger modules from different android modules (would be so helpful specially for instantApp) or from different android build types.

But thanks anyway, I will look for other possibilities as well.