I want to inject a sequence of components where each component implements the same interface. Each of the components may have dependencies themselves which may vary amongst the different implementations of the interface. The actual sequence shall be configurable by the user by means of a configuration file or any mechanism that is made available through the dependency injection framework (guice).
To be more concrete I'll give an example:
interface Machine {...}
class Dishwasher implements Machine {
// Here some dependencies should be injected.
}
class VacuumCleaner implements Machine {
// Here some dependencies should be injected.
}
class Household {
// Here I want to inject a sequence of `Machine`s.
}
// Now the user may specify in whatever way which machines are present in the household,
// and this setting is not changing during runtime.
// For example (using an arbitrary notation):
//
// Household
// |
// |---- Machines
// |
// |---- Dishwasher
// | |
// | |----- SomeDepedencyForDishwasher
// | |----- AnotherDepedencyForDishwasher
// |
// |----- VacuumCleaner
// | |
// | |----- SomeDependencyForVacuumCleaner
// |
// |----- VacuumCleaner
// | |
// | |----- AnotherDependencyForVacuumCleaner
//
//
// So the household would have three `Machine`s, two of which are `VacuumCleaner`s
// (where each `VacuumCleaner` itself depends on a different implementation of another interface)
// and one `Dishwasher`.
How can I realize this using guice? I could write a custom provider for the `Machine`s (i.e. a `MachineFactory`), however the pattern that "a component depends on a sequence of others with dependencies themselves" may repeat further down the chain, so I would be forced to write providers/factories for all of them. This somehow breaks the purpose of dependency injection where I can request a component and all dependencies are resolved automatically by the framework. Furthermore it requires the factory to have knowledge about the possible dependencies of all implementations of the interface which breaks the separation of dependencies from the application: whenever I add a new implementation (a new Machine, e.g. `WashingMaschine`) I need to check whether the factory already requests all required dependencies for the `WashingMaschine` in order to "inject" them manually into the `WashingMaschine` later on. If a new dependency is introduced I need to fix the factory accordingly.
Any ideas? Thanks! Cheers, Dominik