Hi Brian, thanks for taking a shot at it. I'm not offended at all.
You're right that this is a potential code smell, and I've been
rethinking my design to see if I can improve it. My question about
your solution revolves around these two lines:
public DProvider(Whatever dNeeds) { .. }
...
D newD = createDBasedOnWhateverRuntimeCriteria();
In my program, D is essentially a domain object created external to
the system (say, through customer input). I want class C (and
indirectly, A and B) to operate differently on what D is, based on
what the customer gave me. My API to the outside world exposes only
class A, so that's the only way the new D gets into the system.
Using a Provider is exactly what I would want (and my first choice),
if I can can change what D returns each time get() is invoked. The
problem is, how do I get that information to DProvider (from A) at
runtime? I could add a static method to A that DProvider could
invoke, but that's nasty non-OO stuff. Fred's solution works because
the scope.seed() method allows me to change what "D.class" was bound
to at runtime. The Provider approach is much preferred, but I don't
have control over the Provider's construction.
As I've gone the rounds with this and tried everyone's solutions, I'm
thinking at this point my real problem is that A knows about D, and it
probably shouldn't. So maybe I need to go back to the drawing board
and avoid this conundrum altogether.
Thanks again for trying,
Ryan
On Dec 9, 8:40 pm, Brian Lough <[email protected]> wrote:
> lol. Freehand strikes. Naturally the .get() method needs to have code
> prior to the != null if an external force/trigger can instantiate another D
> instance. I'm usually dealing with listener threads that replace the
> contents of currentD out from under me whenever. Cheers!
>
>
>
>
>
>
>
> On Thu, Dec 9, 2010 at 7:36 PM, Brian Lough <[email protected]> wrote:
> > No offense, IMHO, what you're trying to do just smells bad. There's a
> > unnecessary coupling of these classes causing these gyrations that I can't
> > put my finger on. I'm swapping one runtime instance for another easily way
> > down in dependency chains just by using sub-classes of Provider and .get().
> > D is the wonky one, so maybe this will lead somewhere....(typing freehand
> > so..)
>
> > public class DProvider implements Provider<D> {
>
> > private AtomicReference<D> currentD = new AtomicReference<D>(null);
>
> > @Inject
> > public DProvider(Whatever dNeeds) { .. }
> > public D get() {
> > if (currentD.get() != null) {
> > return currentD.get();
> > }
>
> > D oldD = currentD.get();
> > oldD.releaseResources();
> > D newD = createDBasedOnWhateverRuntimeCriteria();
> > currendD.set(newD);
> > return newD;
> > }
>
> > Anyone requiring an instance of D, regardless of position in the dependency
> > chain, gets DProvider injected. As long as they get their D instance via
> > injectedDProvider.get() anytime they access a method of D, they're certain
> > to get whatever runtime instance you've swapped in/out.
>
> > Hope this helps. Took a shot. :-D
--
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.