Search code examples
javadependency-injectionannotationsinversion-of-controlguice

Is it possible to use custom annotations instead of @Named in top of @Provides?


Assume we want to @Inject Strings. I create the Module:

public class StringModule extends AbstractModule{
    @Provides
    String black() {
        return "black";
    }

    @Provides
    String white() {
        return "white"
    }
}

and now I ask for the injected value:

@Inject
private String wantWhiteHere;

Obviously Guice will throw an error because the binding is ambiguous. I know that i can get white if I use the @Named annotation like that:

public class StringModule extends AbstractModule{
    @Named("black")
    @Provides
    String black() {
        return "black";
    }

    @Named("white")
    @Provides
    String white() {
        return "white"
    }
}

and then:

@Named("white")
@Inject
private String iGotWhiteHere;

But what I want is this:

public class StringModule extends AbstractModule{
    @Black
    @Provides
    String black() {
        return "black";
    }

    @White
    @Provides
    String white() {
        return "white"
    }
}

.

@White
@Inject
private String tryingToGetWhiteHere;

Is it possible? When I do it the exception:

A binding to java.lang.String was already configured...

Is there anything anywhere that I can configure to achieve it?

My version of Guice is 4.2.3


Solution

  • Use @Qualifier

    Yes, it is possible. Make sure that you have the following declaration:

    @javax.inject.Qualifier
    @Target({ FIELD, PARAMETER, METHOD })
    @Retention(RUNTIME)
    public @interface White { }
    

    You can find more info on Guice's official wiki.