Well, if you notice in my example, I didn't remove the annotations from
the injected class. I simple changed the annotation to indicate the
role that was played by the class (federal vs commercial) rather than
specifying the implementation. Then the module maps from role ->
implementation.
So, @Named("xxx") annotations don't get in the way of the rule, but what
"xxx" actually is might get in the way.
As a quick example to help aid in understanding. Say that we want to
move commercial sales to the high pricing strategy. All I would need to
do is modify one line in the module (or maybe more if there are multiple
classes involved in "high pricing strategy"):
bind(
IPricingStrategyA.class).annotatedWith(Names.named("commercial")).to(LowPricingStrategyA.class);
becomes
bind(
IPricingStrategyA.class).annotatedWith(Names.named("commercial")).to(HighPricingStrategyA.class);
-Jared
On 09/14/2012 11:57 AM, David Hoffer wrote:
> 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] <mailto:[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] <mailto:[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]
>>>> <mailto:[email protected]>.
>>>> To unsubscribe from this group, send email to
>>>> [email protected]
>>>> <mailto:[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]
>>> <mailto:[email protected]>.
>>> To unsubscribe from this group, send email to
>>> [email protected]
>>> <mailto:[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]
>> <mailto:[email protected]>.
>> To unsubscribe from this group, send email to
>> [email protected]
>> <mailto:google-guice%[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] <mailto:[email protected]>.
>> To unsubscribe from this group, send email to
>> [email protected]
>> <mailto:[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]
> <mailto:[email protected]>.
> To unsubscribe from this group, send email to
> [email protected]
> <mailto:google-guice%[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.