I would do the "class" solution in a more OO way (eliminate the "switch"):
public class MyModule extends AbstractModule {
@Override
protected void configure() {
bind(GenericExecutorProvider.class)
.annotatedWith(Names.named("single"))
.to(SingleProvider.class);
bind(GenericExecutorProvider.class)
.annotatedWith(Names.named("pool"))
.to(PoolProvider.class);
}
}
abstract class GenericExecutorProvider implements Provider<ExecutorService> {
public abstract ExecutorService get();
}
class SingleProvider extends GenericExecutorProvider {
@Inject
SingleProvider(final SomeDependency d) { }
public ExecutorService get() {
// construct and return an ExecutorService
// based on SomeDependency
return null;
}
}
class PoolProvider extends GenericExecutorProvider {
@Inject
PoolProvider(final AnotherDependency d) { }
public ExecutorService get() {
// construct and return an ExecutorService
// based on AnotherDependency
return null;
}
}