A new command

Let’s add a new command for logging in to the ATM:

final class LoginCommand extends SingleArgCommand {
  private final Outputter outputter;

  @Inject
  LoginCommand(Outputter outputter) {
    this.outputter = outputter;
  }

  @Override
  public String key() {
    return "login";
  }

  @Override
  public Result handleArg(String username) {
    outputter.output(username + " is logged in.");
    return Result.handled();
  }
}

(The abstract SingleArgCommand we’re using for simplicity is defined here).

We can create a LoginCommandModule like our HelloWorldModule to bind LoginCommand as a Command:

@Module
abstract class LoginCommandModule {
  @Binds
  abstract Command loginCommand(LoginCommand command);
}

To start using the LoginCommand in CommandRouter, we’ll replace HelloWorldModule in the @Component annotation with LoginCommandModule.

  @Component(modules = {LoginCommandModule.class, SystemOutModule.class})
  interface CommandRouterFactory {
    CommandRouter router();
  }

Run the application and try to log in by typing login <your name>.

This begins to show some of the benefits of using Dagger. With a one line declarative change, we were able to change what Command was received by CommandRouter. CommandRouter had no changes, it just worked. Using this approach, you can write many different versions of your application and reuse code without massive changes.

Previous · Next