The dagger frame is used to handle the creation of objects for you. If you start some kind of initialization in one of your classes that you want to provide, maybe something is not as it should be (see getAlgoRunner() ).
If you have different types that you want to provide at runtime, you want the factory to create the correct object. Enter the dagger.
You have several ways to achieve what you want. Basically, the module should handle the creation of the object:
@Module public class AlgoRunnerProvider { @Provides public AlgoRunner getAlgoRunner() {
1. @Named annotation (or some other Qualifier )
If you know at compile time which class will be needed, which type, you should use qualifiers.
@Named("Version1") @Inject AlgoRunner mRunner;
Then you can simply provide various implementations from your module:
@Provides @Named("Version1") public AlgoRunner getAlgoRunner() { return new Version1AlgoRunner(); } @Provides @Named("OtherVersion") public AlgoRunner getAlgoRunner(Depends someOtherDependency) { return new OtherVersionAlgoRunner(someOtherDependency); }
2. Switching at runtime
Although you can always use the first option by creating several classes with different dependencies, you might want to choose at runtime. To do this, you need to pass some kind of argument to your module:
@Module public class AlgoRunnerProvider { private final int mType; public AlgoRunnerProvider(int type) { mType = type; } @Provides public AlgoRunner getAlgoRunner() { if(mType == TYPE_A) { return new Version1AlgoRunner(); } else { return new OtherVersionAlgoRunner(); } } }
In this option, you still have the logic of creating inside your module where your dependencies come from.
3. Use different modules
Another approach would be to use different modules. This will be a pure solution if it is defined at compile time (different classes using different modules), rather than choosing logic at run time in the same class.
If you start writing code, for example if typeA then moduleA else moduleB , you should stop and do something else.
You can use the same component, but create it using different modules for different classes, using good old inheritance. Each module simply provides an implementation of AlgoRunner .
Then you would just subclass your module accordingly like this
// did not test the following, something like this... public abstract class MyModule { @Provides public AlgoRunner getAlgoRunner(); } public class MyModuleVersionA extends MyModule { @Provides @Override public AlgoRunner getAlgoRunner() { return new Version1AlgoRunner(); } } public class MyModuleSomethingElse extends MyModule { @Provides @Override public AlgoRunner getAlgoRunner() { return new SomeOtherAlgoRunner(); } }
There are probably even more options, especially if you are starting to mix these approaches, but I think these 3 will be the main tools you can use.