Tag Archives: Guice

Guice Dependency Injection – Assisted

Hi everyone. With this blog post I want to start a new category called “well-intentioned” (German: “gut gemeint”) which is about information on the internet which might lead to misunderstandings.

Today I talk about a blog post from Cédric Beust which is quite well ranked on google:
http://beust.com/weblog/2012/08/21/advanced-dependency-injection-with-guice/

In general I agree with Cédric: Dependency Injection (DI) is a pretty comfortable thing and I don’t want to miss it in any of my projects. Especially guice is a Easy-To-Use concept. I would always recommend to use Constructor injection as it can be simply used without DI as well (e.g. in Unit Tests).

BUT: The example in his blog post could be misleading. (Sadly the exampe on Guice’s website is as bad: https://github.com/google/guice/wiki/AssistedInject)

Here some statements:

Dependency on Guice in all classes

When using a external framework you try to have dependencies to it only in a small part of your software. This makes it easier to switch to a different framework. When you use the @Assisted annotation, you introduce a dependency to guice. This is even worse if you use google’s @Inject annotation. You should always prefer to use @javax.inject.Inject (https://code.google.com/p/atinject/). (In most code snippets in the internet no imports are shown.)

Constructor in the example contains Service and field data

When developing (with Java) you should distinguish clearly between data classes (Entity/DTO/POJO…) and worker classes (Services, Handlers, Controllers, Managers…). The data objects contain the state of your domain’s entities and the worker classes should be stateless.

Dependeny Injection is much more useful for the worker classes. Here you need to build a complex object graph of Processors, Facades, Proxies and more.

In the blog example, the data class uses a service which is not the way you should do it.

Real Life example for Assisted Injection

I tried to come up with a real life example where it is really good advice to use Assisted Injection. As it seems quite hard I’m not sure if there is one at all. Perhaps a Service which gets a Configuration Object which cannot be injected as it needs to be created programmatically (e.g. from a Properties file).

Simple Guice Example

import javax.inject.Inject;

public class AddressValidationService {

 @Inject
 public AddressValidationService(GeoService geoService, AddressConfiguration addressConfiguration) {
 this.addressConfiguration = addressConfiguration;
 this.geoService = geoService;
 }
}

In this simple example we use Constructor injection. So it is quite easy to write a Unit Test for this class as there is no need to use Guice there. Here an example with Mockito:

public class AdressValidationFacadeTest{

@Test
 public void testValidation() {
 GeoService geoService = mock(GeoService.class);
 AddressConfiguration addressConfiguration = mock(AddressConfiguration.class);
 AddressValidationService addressValidation = new AddressValidationService(geoService, addressConfiguration);
 assertTrue(addressValidation.validate());
 }
}

 

Extended example with Assisted Injection

It might be the case that the AddressConfiguration object is not available via injection and therefore needs to be provided manually. To do so, you might consider using assisted injection mechanism, which automatically generates you a Factory class.

You just need to add the Assisted annotation and provide a factory interface which needs to be registered to the FactoryModuleBuilder:

public class AddressValidationService {

  @Inject
 public AddressValidationService(GeoService geoService, @Assisted AddressConfiguration addressConfiguration) {
 this.addressConfiguration = addressConfiguration;
 this.geoService = geoService;
 }

The factory interface:

public interface AddressValidationServiceFactory {

 AddressValidationService create(AddressConfiguration addressConfiguration);
}

In the Guice Module:

public void configure(Binder binder) {
 binder.install(new FactoryModuleBuilder().build(AddressValidationServiceFactory.class));
 }

So when you now use the factory by Injecting it to one of your classes a auto-generated implementation is bound by guice. MAGIC 🙂

Here is the complete maven project: Guice Example With Assisted Injection