Using assistedinject and mapbinder with FactoryModuleBuilder

630 views
Skip to first unread message

Leigh Klotz

unread,
Jul 22, 2010, 2:11:53 PM7/22/10
to google-guice
I seem to ask questions about these three things fairly regularly, so
please bear with me if you find it repetitive.

With earlier versions of assistedinject, I could use
FactoryProvider.newFactory like this:

mapbinder.addBinding("orange").
toProvider(FactoryProvider.newFactory(FruitFactory.class,
Orange.class));
mapbinder.addBinding("banana").
toProvider(FactoryProvider.newFactory(FruitFactory.class,
Banana.class));

@Inject Map<String, FruitFactory> map;
map.get(fruitname).bear(3);

See discussion of this "command" pattern with mapbinder and
assistedinject here: http://tinyurl.com/22t28y6

With FactoryModuleBuilder, I'm not sure how to obtain the Provider
object to put into the mapbinder.

Below are some half-baked ideas I've pursued; if you already know what
I mean by reading the above, this part probably will just be
confusing.

I did see that I can create annotated providers, in answer to a
question I asked about FactoryModuleBuilder: http://tinyurl.com/2baormz

But it's not clear to me that this gives me the indirection I need to
bear dynamic fruit.

I also see you can use TypeLiteral with FactoryModuleBuilder. So
perhaps I could simply drop the mapbinder altogether and change Fruit
to be Fruit<T> and let Guice's type mechanism satisfy the type
injection of FruitFactory<Orange>, but I still lack the indirection
necessary to obtain a FruitFactory where the fruit class is known only
at runtime.

Thank you,
Leigh.

Fred Faber

unread,
Jul 22, 2010, 2:13:41 PM7/22/10
to google...@googlegroups.com
To be honest, I ran into that same limitation myself and concluded the most straightforward solution was to use the deprecated FactoryProvider.newFactory() method.  I didn't want to introduce any more levels of indirection when there was a clear and understandable working solution.

I'll sit back and watch this thread to see what other folks think as well.

-Fred


--
You received this message because you are subscribed to the Google Groups "google-guice" group.
To post to this group, send email to google...@googlegroups.com.
To unsubscribe from this group, send email to google-guice...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-guice?hl=en.


Sam Berlin

unread,
Jul 22, 2010, 5:01:26 PM7/22/10
to google...@googlegroups.com
I haven't tested this (and am writing it on my phone), but try
installing FactoryModuleBuilder as normal and then binding the
mapbinder with mapBinder.addBinding(blah).toProvider(getProvider
(MyFactory.class)). "getProvider" being the important bit here.

Sam

Leigh Klotz

unread,
Jul 23, 2010, 6:42:59 PM7/23/10
to google-guice
Unless I'm mistaken, that would work if there's only one provider, but
the FactoryProvider mechanism allows for creation of multiple
providers which are essentially anonymous until named (made reachable)
by inclusion in the mapbinder.

The various links in the original post about the command pattern show
the use case in more detail, but the code snippets about orange and
banana directly in the original message are enough to see it (if not
to motivate it the use case). Both are implementations of interface
FruitFactory but neither is bound to FruitFactory.class.

Leigh.

On Jul 22, 2:01 pm, Sam Berlin <sber...@gmail.com> wrote:
> I haven't tested this (and am writing it on my phone), but try  
> installing FactoryModuleBuilder as normal and then binding the  
> mapbinder with mapBinder.addBinding(blah).toProvider(getProvider
> (MyFactory.class)). "getProvider" being the important bit here.
>
> Sam
>

Sam Berlin

unread,
Jul 23, 2010, 7:13:21 PM7/23/10
to google...@googlegroups.com, google-guice
Ahhh - I understand what you're going for. Something similar to this
came up internally recently. How about this as a workaround:
for ( Fruit fruit : Fruit.values() ) {
Key key = Key.get(FactoryModuleBuilder.class,
UniqueAnnotation.create());
install(new FMB().build(key));
mapBinder.addBinding(fruit).toProvider(getProvider(key));
}

UniqueAnnotations is package-private to Guice, so you'll have to
recreate it (or you can use a named binding keyed off the enum).

This is a pretty solid use-case, though, and FactoryModuleBuilder
could easily have a getProvider method in it to make this easier.

(FYI, code samples written on my phone while on an Amtrak train whose
engine broke, so we're literally "rolling" from stop to stop. So it
won't compile, but it's unnecessarily detailed for phone code.)

Sam

Leigh Klotz

unread,
Aug 2, 2010, 6:28:28 PM8/2/10
to google-guice
Thank you. I have opened a bug on this so it can be decided, once
Amtrak gets the engine restarted.

http://code.google.com/p/google-guice/issues/detail?id=530

Leigh.

On Jul 23, 4:13 pm, Sam Berlin <sber...@gmail.com> wrote:
> Ahhh - I understand what you're going for. Something similar to this  
> came up internally recently. How about this as a workaround:
>    for ( Fruit fruit : Fruit.values() ) {
>      Key key = Key.get(FactoryModuleBuilder.class,  
> UniqueAnnotation.create());
>       install(new FMB().build(key));
>      mapBinder.addBinding(fruit).toProvider(getProvider(key));
>    }
>
> UniqueAnnotations is package-private to Guice, so you'll have to  
> recreate it (or you can use a named binding keyed off the enum).
>
> This is a pretty solid use-case, though, and FactoryModuleBuilder  
> could easily have a getProvider method in it to make this easier.
>
> (FYI, code samples written on my phone while on an Amtrak train whose  
> engine broke, so we're literally "rolling" from stop to stop.  So it  
> won't compile, but it's unnecessarily detailed for phone code.)
>
> Sam
>

Itay Yahimovitz

unread,
Oct 1, 2013, 12:40:28 AM10/1/13
to google...@googlegroups.com
It's been so long and still not official solution?
I'm still using FactoryProvider, there is no other option for injecting multiple providers to a MapBinder
Reply all
Reply to author
Forward
0 new messages