Dependency injection with Guice

Guice is the new kid on the block in the context dependency injection field. It tries not to be a complete stack like Spring, but merely a very useful addition, which does not carry grown structures around like Spring does. It has been developed by Google and is used in some of their applications, for example, in Google Docs, Adwords, and even YouTube.

The source code of this recipe is available in the chapter3/guice directory.

Getting ready

This example implements the same encryption service as the Spring example, so the only thing that changes is actually the controller implementation. You should have installed the Guice module by now, using the dependencies.yml file.

How to do it...

First a Guice module needs to be defined, where the interface is glued to the implementation:

public class GuiceModule extends AbstractModule {

    @Override
    protected void configure() {
    bind(EncryptionService.class).to(EncryptionServiceImpl.class);
    }
}

After that the controller can be written in the following way:

public class Application extends Controller {

    @Inject
    private static EncryptionService encService;

    public static void decrypt() {
        renderText(encService.decrypt(params.get("text")));
    }

    public static void encrypt() {
        renderText(encService.encrypt(params.get("text")));
    }
}

How it works...

As you can see, the @Inject annotation helps to keep code outside of the controller methods. This means any method can access the service object as it is defined as static. This also implies that you should never store state in such an object, the same as with any Spring bean. Also, be aware that you should import javax.inject.Inject and not the com.google.inject.Inject class in to inject your service correctly.

There's more...

Now let's talk about some other options, or possibly some pieces of general information that are relevant to this task.

Default @Inject support of play

The Guice module has basic support for the @Inject annotation, where you do not need to specify a mapping from an interface to a concrete implementation in the class which extends AbstractModule, like GuiceModule in this example. However, it works only for classes, which are either a Job, a Mailer, or implement the ControllerSupport interface. The following snippet would return the current date in a controller whenever it is called:

    @Inject
    private static DateInjector dater;

      public static void time() {
        renderText(dater.getDate());
    }

The DateInjector would be defined as the following:

public class DateInjector implements ControllerSupport {

    public Date getDate() {
        return new Date();
    }
}

Keep in mind that the class you are injecting is always a singleton. Never store some kind of state inside its instance variables. Also this injection still needs to have the Guice module loaded.

Creating own injectors

The Guice module also supports the creation of own injectors. Please check the official documentation for more information as it is well described in there.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.139.80.209