2014-04-27

Guice Tutorial - 06 - Injecting injector

Introduction

Suppose you need a factory which gives you one implementation of interface depends on given parameter. The number of possible implementations is quite big. It could be resolved with factory with injected providers of each implementation, but in Guice we have a better way to achieve this goal...

Main

We could inject Injector to our class. We have a builder factory which could gives us implementation based on parameter:
public class BuilderFactory {
    private Injector injector;

    @Inject
    public BuilderFactory(final Injector injector) {
        this.injector = injector;
    }

    public Builder getBuilder(String param){
    if("first".equals(param)){
        return injector.getInstance(FirstBuilder.class);
        } else if("second".equals(param)){
            return injector.getInstance(SecondBuilder.class);
        } else {
            return injector.getInstance(DefaultBuilder.class);
        }
    }
}
And there are builders:
public interface Builder {}
public class FirstBuilder implements Builder{}
public class SecondBuilder implements Builder{}
public class DefaultBuilder implements Builder{}

First, to test is simply get injector from injector:
@Test
public void shouldInjectInjectorFromInjector(){
    //given
    Injector sut = Guice.createInjector();
    //when
    Injector result = sut.getInstance(Injector.class);
    //then
    assertEquals(sut, result);
}

Now let's get specific builder from our BuilderFactory:
@Test
public void shouldGetFirstBuilderFromFactory(){
    //given
    Injector sut = Guice.createInjector();
    BuilderFactory builderFactory = sut.getInstance(BuilderFactory.class);
    //when
    Builder builder = builderFactory.getBuilder("first");
    //then
    assertTrue(builder instanceof FirstBuilder);
}

@Test
public void shouldGetSecondBuilderFromFactory(){
    //given
    Injector sut = Guice.createInjector();
    BuilderFactory builderFactory = sut.getInstance(BuilderFactory.class);
    //when
    Builder builder = builderFactory.getBuilder("second");
    //then
    assertTrue(builder instanceof SecondBuilder);
}

@Test
public void shouldGetDefaultBuilderFromFactory(){
    //given
    Injector sut = Guice.createInjector();
    BuilderFactory builderFactory = sut.getInstance(BuilderFactory.class);
    //when
    Builder builder = builderFactory.getBuilder("unknown");
    //then
    assertTrue(builder instanceof DefaultBuilder);
}
And every tests pass.

Conclusion

When we have to create factory which gives us many concrete implementation we could inject injector to factory to not inject many providers of this concrete implementations. Source code is available here.

No comments:

Post a Comment