A pattern to mitigate the boilerplate is to use a parameterized annotation:
@Retention(RetentionPolicy.RUNTIME)
@BindingAnnotation
public @interface DoesFooStuff {
FooClient value();
enum WhatKindOfStuff {
STUFF_THAT_A_WANTS,
STUFF_THAT_B_WANTS,
...
STUFF_THAT_Z_WANTS
}
}
You would then use this to annotate your Foos:
FooClient class AFoo {
@Inject AFoo(@DoesStuffForFoo(Foo.WhatKindOfStuff.STUFF_THAT_A_WANTS)
IFoo foo) {
...
}
}
In your module you'd define an implementation of the interface (which
is tricky...you need to be careful to follow the spec on the
Annotation javadoc):
@SuppressWarnings("ClassExplicitlyAnnotation")
private static class DoesFooStuffImpl implements DoesStuffForFoo {
private final WhatKindOfStuff value;
private DoesFooStuffImpl(WhatKindOfStuff value) {
this.value = value;
}
@Override WhatKindOfStuff String value() {
return value;
}
@Override public Class<? extends Annotation> annotationType() {
return DoesStuffForFoo.class;
}
@Override public String toString() {
return "@" + DoesStuffForFoo.class.getName() + "(value=" + value + ")";
}
@Override public boolean equals(Object o) {
return o instanceof DoesStuffForFooImpl
&& ((DoesStuffForFoo) o).value().equals(value());
}
@Override public int hashCode() {
return (127 * "value".hashCode()) ^ value.hashCode();
}
}
You could then define a helper method as syntatic sugar over the binding:
private void bindFoo(Class<? extends Foo> fooClass, WhatKindOfStuff
whatKindOfStuff {
bind(Foo.class)
.annotatedWith(new DoesFooStuffImpl(whatKindOfStuff))
.to(fooClass);
}
And then your bindings become:
@Override protected void configure() {
bindFoo(FooThatAFooWants.class, WhatKindOfStuff.STUFF_THAT_A_WANTS);
bindFoo(FooThatBFooWants.class, WhatKindOfStuff.STUFF_THAT_B_WANTS);
...
bindFoo(FooThatZFooWants.class, WhatKindOfStuff.STUFF_THAT_Z_WANTS);
}
Fred
On Fri, Sep 7, 2012 at 3:02 AM, robertdup <[email protected]> wrote:
> Yes it's right.. but this way don't satisfy me totally cause I have some
> XFoo classes.
> I will have to create many annotation (@A,@B, ..., @Z), and I must bind
> all of them or I will get a guice exception.
>
> bind(IFoo.class).annotatedWith.(A.class).to(DefaultFoo.class);
> bind(IFoo.class).annotatedWith.(B.class).to(DefaultFoo.class);
> [...]
> bind(IFoo.class).annotatedWith.(Y.class).to(DefaultFoo.class);
> bind(IFoo.class).annotatedWith.(Z.class).to(DefaultFoo.class);
>
> In my case, I just have to override a couple of binding and let the other
> on the default implementation (DefaultFoo.class)
> bind(IFoo.class).annotatedWith.(E.class).to(MyEFoo.class);
> bind(IFoo.class).annotatedWith.(K.class).to(MyKFoo.class);
>
> Otherwise, PrivateModule looks too "heavy" to implement in my case..
>
>
> - Well, Is there an other way that could be less verbose ?
>
>
> Best regards;
>
>
> On Friday, September 7, 2012 3:59:12 AM UTC+2, Fred Faber wrote:
>
>> Strictly speaking, the robot legs problem describes a scenario where the
>> types of your object chain are identical. In your case, you wouldn't have
>> AFoo and BFoo, but just Foo. It's a luxury of sorts to have AFoo and BFoo
>> because you _can_ use a binding annotation on the constructor of each.
>> That is the solution I would prefer for its clarity in how AFoo and BFoo
>> are being configured:
>>
>> class AFoo {
>> @Inject AFoo(@DoesStuffRelatedToA IFoo ifoo) { ... }
>> }
>>
>> class BFoo {
>> @Inject BFoo(@DoesStuffRelatedToB IFoo ifoo) { ... }
>> }
>>
>> Here, grepping through the code directly for DoesStuffRelatedToA would
>> lead me to the binding for IFoo in context of AFoo, and that's a little bit
>> of a win for code maintenance.
>>
>> Fred
>>
>> On Thu, Sep 6, 2012 at 12:51 PM, robertdup <[email protected]> wrote:
>>
>>> Thanks for your reply.
>>>
>>> Do you know if it's a common uses to have more than 20 privates modules ?
>>>
>>>
>>>
>>> On Thursday, September 6, 2012 4:00:35 PM UTC+2, Thomas Broyer wrote:
>>>>
>>>> This is known as the "robot legs" problem, see
>>>> http://code.google.com/p/**g**oogle-guice/wiki/**FrequentlyAsk**
>>>> edQuestions#How_**do_I_build_**two_similar_but_**slightly_**
>>>> different_trees_of_**objec<http://code.google.com/p/google-guice/wiki/FrequentlyAskedQuestions#How_do_I_build_two_similar_but_slightly_different_trees_of_objec>
>>>>
>>>> On Thursday, September 6, 2012 9:14:24 AM UTC+2, robertdup wrote:
>>>>>
>>>>> Hello there,
>>>>>
>>>>> I trying to implement default binding on my module without any
>>>>> success...
>>>>>
>>>>> Here is what I would like to do (*my dream*) :
>>>>>
>>>>> class AFoo
>>>>>> {
>>>>>> @Inject AFoo( IFoo foo ){}
>>>>>> }
>>>>>>
>>>>>> class BFoo
>>>>>> {
>>>>>> @Inject BFoo( IFoo foo ){}
>>>>>> }
>>>>>>
>>>>>>
>>>>>> bind(IFoo.class).to(**DefaultFoo**.class);
>>>>>> bind(IFoo.class).to(OtherFoo.**c**lass)*.on(BFoo.class)*;
>>>>>>
>>>>>
>>>>>
>>>>> I know that I could solve this problem using annotation like this :
>>>>>
>>>>> class AFoo
>>>>>> {
>>>>>> @Inject AFoo( @A IFoo foo ){}
>>>>>> }
>>>>>>
>>>>>> class BFoo
>>>>>> {
>>>>>> @Inject BFoo( @B IFoo foo ){}
>>>>>> }
>>>>>>
>>>>>>
>>>>>> bind(IFoo.class).**annotatedWith**(A.class).to(**DefaultFoo.class)**;
>>>>>> bind(IFoo.class).**annotatedWith**(B.class).to(**OtherFoo.class);
>>>>>>
>>>>>
>>>>> But this way is too boring and dirty.. (because I have to add
>>>>> annotation/binding definition for each one)
>>>>>
>>>>>
>>>>> - *Are there some others ways to solve Default binding "problem" ?*
>>>>>
>>>>> Thanks in advance; Best regards
>>>>>
>>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "google-guice" group.
>>> To view this discussion on the web visit https://groups.google.com/d/**
>>> msg/google-guice/-/**bqRh1CKDwsEJ<https://groups.google.com/d/msg/google-guice/-/bqRh1CKDwsEJ>
>>> .
>>>
>>> To post to this group, send email to [email protected].
>>> 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<http://groups.google.com/group/google-guice?hl=en>
>>> .
>>>
>>
>>
--
You received this message because you are subscribed to the Google Groups
"google-guice" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/google-guice?hl=en.