Guice: Using @Named to create object
The best way to do this is not with a factory but with @Provides
methods. My company uses Guice very, very extensively, and requestInjection
is always considered a bad idea because it can easily set up a very fragile graph of implicit dependencies.
Here's what it should look like:
public class FooModule extends AbstractModule {
protected void configure() {
// do configuration
}
@Provides
@Named("white")
Color provideWhiteColor(ColorSet colorSet) {
return colorSet.white(); // or whatever
}
@Provides
@Named("black")
Color provideBlackColor(ColorSet colorSet) {
return colorSet.black(); // or whatever
}
// etc
}
There are few code bases where I have seen the use of injector directly in order fetch certain object.
injector.getInstance(Color.class);
In this case, you can use the following:
injector.getInstance(Key.get(Color.class, Names.named("light")));
You could setup a factory within the module, and request injection on it to fill in the ColorSet.
Module:
ColorFactory colorFactory = new ColorFactory();
requestInjection(colorFactory);
bind(Color.class).annotatedWith(Names.named("light")).toInstance(colorFactory.buildColor("white"));
bind(Color.class).annotatedWith(Names.named("dark")).toInstance(colorFactory.buildColor("black"));
ColorFactory:
public class ColorFactory {
private ColorSet colorSet;
public Color buildColor(String color){
return new Color(colorSet, color);
}
@Inject
public void setColorSet(ColorSet colorSet) {
this.colorSet = colorSet;
}
}