On Wed, Mar 19, 2014 at 2:02 PM, Philipp Wendler <[email protected]>wrote:

> Hi,
>
> Am 19.03.2014 18:37, schrieb Mike Grove:
> > On Wed, Mar 19, 2014 at 1:32 PM, Philipp Wendler <[email protected]
> >wrote:
> >> Am 19.03.2014 17:20, schrieb Mike Grove:
> >>> I'd like to have some default implementation of an interface, and then
> >> in a
> >>> separate module, provide a new implementation which uses the old one,
> via
> >>> the decorator pattern.  And everywhere that should have gotten the
> >> default,
> >>> gets the overridden one, and the modified behavior.
> >>
> >> I had the same problem, and developed a solution that I described here:
> >> http://stackoverflow.com/q/7416974/396730
> >
> >
> > Looks promising.  Is the source for your annotation & utilities available
> > anywhere?
>
> So far no.
> I ended up not using it for other reasons, and so I never added tests
> etc. and made it available online. I could do so, but it would need some
> time I guess.
>
> If you have a hard-coded chain of decorators, you could probably leave
> out the most complicated part (which is the overriding of bindings) and
> just declare the bindings by hand:
> A.class annotatedWith(InInstance(B.class)) to A.class
> A.class to B.class
>
> Maybe you need to use a common interface for A and B that is used as the
> actual binding, not sure if the above works directly. With an interface
> it looks like this:
> I.class annotatedWith(InInstance(B.class)) to A.class
> I.class to B.class
>

Actually, this.  Doing the obvious modification to my example, leaving A as
the base class and B extending it with no interface common to the two did
not work.  When adding an interface I, which is common to both, seemed to
do the trick.  Otherwise, I still got the circular binding exception.

This should work for me, i think, for my current use case.

I appreciate the pointer.

Below is my final code example which illustrates it working for future
reference.

Cheers,

Mike

public class TestModuleOverride {

public static void main(String[] args) {
Module base = new AbstractModule() {
@Override
protected void configure() {
bind(I.class).to(A.class);
}
};

Module override = new AbstractModule() {
@Override
protected void configure() {
bind(I.class).annotatedWith(Foo.class).to(A.class);
bind(I.class).to(B.class);
}
};

Injector i = Guice.createInjector(Modules.override(base).with(override));

System.err.println(i.getInstance(I.class).doSomething());
}

public static interface I {
public String doSomething();
}

public static class A implements I {
public String toString() { return "A";}

public String doSomething() { return "A is doing something"; }
}

public static class B implements I {
private I a;
@Inject
public B(final @Foo I theA) { a = theA; }

public String toString() { return "B" + a;}

public String doSomething() { return "B is doing something, " +
a.doSomething(); }
}

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@BindingAnnotation
public @interface Foo {
}
}



>
> The InInstance annotation does not contain anything big, it is just a
> regular annotation (you can take a look at the implementation of Named).
>
> Greetings,
> Philipp
>
> --
> You received this message because you are subscribed to the Google Groups
> "google-guice" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/google-guice.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/google-guice.
For more options, visit https://groups.google.com/d/optout.

Reply via email to