I think that makes sense.  I like the guiding rule as you put
it..."keep decisions about which implementation to use at the Module level,
not at the injected class level."

Just not sure I can in practice I know how to use Guice fully following
that rule...as without class level annotations I don't know how you could
ever use more than one concrete instance of an interface in any one
application.  (That was my original use of annotations so I could have lots
of IProcessor instances, for instance.  Now I have groups of instances that
must be switched out as a group.)

So it seems that the @Named("xxx") annotation gets in the way of that rule.
 Even in your case what determines what will be injected is
the commercial/federal annotations.

Regarding custom annotations...does that solve this?  I have not used them
yet.  Also I'm not familiar with the robot legs pattern...I'll have to
investigate that.

-Dave



On Fri, Sep 14, 2012 at 10:02 AM, Jared Bunting <[email protected]
> wrote:

>  I'm also not an expert, but one of my guiding rules is, like Stuart said,
> to keep decisions about which implementation to use at the Module level,
> not at the injected class level.  So in this case, I would probably do
> something like this:
>
> @Inject
> public MyClass(IPricingStrategyA pricingStrategyA,
>                                         ICalculator calculator) {
>         this.pricingStrategyA = pricingStrategyA ;
>         this.calculator = calculator;
>    }
>
>  then in the module:
>  protected void configure() {
>         bind( IPricingStrategyA.class).to(LowPricingStrategyA.class);
>         bind( ICalculator.class).to(APRCalculator.class);
> ...
>
>  If I have some clients that need the low strategy and some that need the
> high, I might do something like this:
>
> @Inject
> public CommercialSales(@Named("commercial") IPricingStrategyA
> pricingStrategyA,
>                                         ICalculator calculator) {
>         this.pricingStrategyA = pricingStrategyA ;
>         this.calculator = calculator;
>    }
>
>  @Inject
> public FederalSales(@Named("federal") IPricingStrategyA pricingStrategyA,
>                                         ICalculator calculator) {
>         this.pricingStrategyA = pricingStrategyA ;
>         this.calculator = calculator;
>    }
>
>  then in the module:
>  protected void configure() {
>         bind(
> IPricingStrategyA.class).annotatedWith(Names.named("commercial")).to(LowPricingStrategyA.class);
>
> bind( 
> IPricingStrategyA.class).annotatedWith(Names.named("federal")).to(HighPricingStrategyA.class);
>         bind( ICalculator.class).to(APRCalculator.class);
>  ...
>
>  (although in reality I would probably use a custom annotation, rather
> than @Named, or at the very least, constants for the strings...but you get
> the point)
>
> In both of these patterns, you can see that the decision about what
> implementation to use is all contained in the module, thus keeping it in
> the same location.
>
> This could also be accomplished with the robot legs pattern, and there's
> probably some good arguments for doing it that way.
>
> -Jared
>
>
> On 09/14/2012 09:40 AM, David Hoffer wrote:
>
> I'm quite new to Guice so perhaps I'm doing things wrong but I use this
> pattern a lot:
>
>  @Inject
> public MyClass(@Named("LowPricingStrategyA") IPricingStrategyA
> pricingStrategyA,
>                                         ICalculator calculator) {
>         this.pricingStrategyA = pricingStrategyA ;
>         this.calculator = calculator;
>    }
>
>  then in the module:
>  protected void configure() {
>         bind(
> IPricingStrategyA.class).annotatedWith(Names.named("LowPricingStrategyA")).to(LowPricingStrategyA.class);
>
> bind( 
> IPricingStrategyA.class).annotatedWith(Names.named("HighPricingStrategyA")).to(HighPricingStrategyA.class);
>         bind( ICalculator.class).to(APRCalculator.class);
>  ...
>
>  Note that for IPricingStrategyA I have two possible
> bindings LowPricingStrategyA & HighPricingStrategyA, the module doesn't
> know/specify which will be used, that is determined by
> the @Named("LowPricingStrategyA") annotation in MyClass.  Now imagine the
> 'pricing strategy group' has 5 pairs of classes A, B, C, D & E...a High and
> a Low for each.
>
>  What I'm wondering is how to get the control of this centralized instead
> of in 5 different classes.
>
>  -Dave
>
>
> On Fri, Sep 14, 2012 at 8:25 AM, Stuart McCulloch <[email protected]>wrote:
>
>>   On 14 Sep 2012, at 15:16, Christian Gruber wrote:
>>
>>  I feel like I need a bit more clarity of what you're trying to do
>> before commenting properly.  There are a few ways to think about what you
>> describe here, but without a concrete example in code, it's hard to reason
>> about what might be the best solution.  Can you create a simplified example
>> in code and paste it here, so we can better help?
>>
>>
>>  IMHO the real control should be in the module (ie. what gets bound to
>> which key) and not in the concrete class - that should just declare what it
>> needs (ie. its injected dependencies). If you have duplicate graphs of
>> objects which only differ in price strategy then that sounds like the
>> "robot-legs" problem:
>> http://code.google.com/p/google-guice/wiki/FrequentlyAskedQuestions#How_do_I_build_two_similar_but_slightly_different_trees_of_objec
>>
>> On Friday, September 14, 2012 at 10:00 AM, dhoffer wrote:
>>
>>  I've got a couple of projects that use Guice that used to use manual
>> DI.  So currently I have one module class with all the bindings.  I often
>> use the annotatedWith(Names.named("MyClass")) approach so I can specify
>> which implementation should be injected.
>>
>>  But this brings me to the problem.  What if I have the case where
>> several injections much change as a set?  E.g. lets say I'm implementing a
>> couple of pricing strategies where each strategy creates 5 concrete
>> classes...it's critical that all 5 of those are from the same pricing
>> strategy...not 4 from one and 1 from another.  In the old days, pre-Guice,
>> I could just go to my 'application construction method' find the 5 relevant
>> classes put them right next to each other in code...add comments/etc.  E.g.
>> everything was all in one place so it was manageable to find what types are
>> being created and switch things out.
>>
>>  Now post-Guice I have no centralized control of anything...as the
>> module file doesn't say what is created it just says if 'you' find X use Y.
>>  The real control is in each java class file's @Inject constructor where I
>> add the  @Named("MyClass") annotation.
>>
>>  How can I achieve a more centralized control over the exact classes
>> instantiated?
>>
>>
>>
>>  --
>> 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/-/PHofIXp_71AJ.
>> 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.
>>
>>
>>
>>  --
>> 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.
>>
>>
>>   --
>> 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.
>>
>
>  --
> 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.
>
>
>  --
> 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.
>

-- 
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.

Reply via email to