How do you inject jdbiFactory DAOs into a Dropwizard Command?

I'm starting to work with Dropwizard and I'm trying to create a Command that requires to use the database. If someone is wondering why I'd want to do that, I can provide good reasons, but this is not the point of my question anyway. It's about dependency inversion and Service initialization and run phases in Dropwizard.

Dropwizard encourages to use its DbiFactory to build DBI instances but in order to get one, you need an Environment instance and/or the database configuration:

public class ConsoleService extends Service<ConsoleConfiguration> {

  public static void main(String... args) throws Exception {
    new ConsoleService().run(args);
  }

  @Override
  public void initialize(Bootstrap<ConsoleConfiguration> bootstrap) {
    bootstrap.setName("console");
    bootstrap.addCommand(new InsertSomeDataCommand(/** Some deps should be here **/));
  }

  @Override
  public void run(ConsoleConfiguration config, Environment environment) throws ClassNotFoundException {
    final DBIFactory factory = new DBIFactory();
    final DBI jdbi = factory.build(environment, config.getDatabaseConfiguration(), "postgresql");
    // This is the dependency I'd want to inject up there
    final SomeDAO dao = jdbi.onDemand(SomeDAO.class); 
  }
}

As you can see, you have the configuration for your Service and its Environment in its run() method, but commands need to be added to the Service's bootstrap in its initialize() method.

So far, I've been able to achieve this by extending ConfiguredCommand in my Commands and creating DBI instances inside their run() methods, but this is a bad design, because dependencies should be injected into the object instead of creating them inside.

I'd prefer to inject DAOs or any other dependencies of my Commands through their constructor, but this seems currently impossible to me, as the Environment and the configuration are not accesible in Service initialization, when I need to create and add them to its bootstrap.

Does anyone know how to achieve this?

Answers


Can you use the EnvironmentCommand?


This is how I use Guice with Dropwizard. Inside your run() method add the line

Guice.createInjector(new ConsoleModule());

Create the class ConsoleModule

public class ConsoleModule extends AbstractModule {

 public  ConsoleModule(ConsoleConfiguration consoleConfig)
 {
     this.consoleConfig = consoleConfig;
 }

 protected void configure()
{
   bind(SomeDAO.class).to(SomeDAOImpl.class).in(Singleton.class)
  }
}

Need Your Help

Python - Better way to convert string and escaped hex string data to integers?

python string integer ascii xbee

I'm working on a project where I receive data from an XBEE radio. The data comes in different strings... I've finally found a way to extract the actual information however, I really think there has...