Guice Questions (with Answers)

I mentioned that ClassBus uses Guice, and received some questions:

Speaking of Guice, don’t you have to reference Guice APIs to bootstrap the dependency injection? In general how should “third party” libraries handle Guice? As an app developer how should I handle libraries that use Guice? Do I care?

First, let me explain how ClassBus uses Guice. ClassBus is a tiny project with a handful of interfaces and classes. For example, BasicEventService depends on a DeliveryStrategy interface:

@Inject
public BasicEventService(DeliveryStrategy deliveryStrategy) {
  this.deliveryStrategy = deliveryStrategy;
}

See that “@Inject”? That’s Guice. The DeliveryStrategy interface declares a default implementation:

@ImplementedBy(EdtDeliveryStrategy.class)
public interface DeliveryStrategy {
 ...
}

That’s because I anticipate most people will use this framework in Swing GUIs and will want event dispatch thread delivery semantics.

I also use the @Singleton tag in one place:

@Singleton
public class BasicEventService implements EventService {
  ...
}

Again, that’s the most common (anticipated) usage pattern.

Ramifications

Using these Guice annotations means I need Guice in my classpath when I compile ClassBus.

Let me be perfectly clear about this: You do not need Guice to use ClassBus. Projects using ClassBus don’t need a Guice JAR file anywhere, either at build or run time.

Of course, if you wish to use dependency injection with Guice, you’ll then need to include Guice in your classpath.

Bootstrap Example

Two of the demonstration programs use Guice. It’s pretty basic stuff:

private static void swingSafeMain() {
  EventService es = Guice.createInjector().getInstance(EventService.class);
  new ProgressDemo(es).setVisible(true);
}
Why Not?

That’s it. One line of code to create the injector and get an implementation of the EventService interface. Since the EventService interface specifies an @ImplementedBy(BasicEventService.class) annotation, you get the default. And since BasicEventService specifies the @Singleton annotation, it is a singleton. And finally, since the BasicEventService constructor uses @Inject, you get the EdtDeliveryStrategy. All by magic.

Non Guice

If you don’t want to use Guice, you just need to either use some other DI framework, or manually construct the classes:

DeliveryStrategy deliveryStrategy = new EdtDeliveryStrategy();
EventService es = new BasicEventService(deliveryStrategy);

Third Party

And finally, this question:

In general how should “third party” libraries handle Guice?

I don’t see any downside to me including Guice annotations in ClassBus. You can ignore them if you don’t use Guice. If you use Guice in your application, then ClassBus will blend right in.


Leave a Reply