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