Issue: Decorator Injection

392 views
Skip to first unread message

big bad joe

unread,
Aug 12, 2007, 6:21:39 AM8/12/07
to google-guice
Im working with decorators and, there, Guice has a lack to handle my
demand.
Look at following scenario:

interface A {}

class B implements A {...}
class C implements A {
// this class is just a decorator
@Inject
public C(A a){...}
}

Now I want to bind B and C to A such that C gets B injected and all
other classes that inject A will get C. Now this is sometimes which is
easily possible with Springs XML configuration (but I dont like Spring
and XML and Im not planing to use it), but handling this problem with
annotations will end up in really ugly code. Moreover, annotations are
useless when you want to use a arbitrary number of decorators and as a
matter of fact I need this.

There is already an Issue with multibindings:
http://code.google.com/p/google-guice/issues/detail?id=37
For my problem, another form of multibinding would be neccessary.

I wanted to have this discussed here, maybe there is a solution that i
did not get? Did anyone else have to use decorators and ran into the
same problem?

Dhanji R. Prasanna

unread,
Aug 12, 2007, 7:19:52 AM8/12/07
to google...@googlegroups.com
Why not use guice aop for decoration?

Bob Lee

unread,
Aug 12, 2007, 10:32:12 AM8/12/07
to google...@googlegroups.com
On 8/12/07, big bad joe <jov...@gmail.com> wrote:
I wanted to have this discussed here, maybe there is a solution that i
did not get? Did anyone else have to use decorators and ran into the
same problem?

Currently, you need to use a custom provider:

bind(A.class).toProvider(AProvider.class);

class AProvider implements Provider<A> {
  @Inject B b;
  public A get() {
    return new C(b);
  }
}

Bob

big bad joe

unread,
Aug 12, 2007, 4:45:47 PM8/12/07
to google-guice
Dhanji,
could you give me a clue how to use aop for decoration? I understand
the principles of aop but I never used it before.

Bob,
unfortunately I have more then one decorator for a class, you can
imagine that your solution is not really applicable in that case.
Anyway, does your "Currently" mean that some upcoming version of Guice
will be able to handle this? I did not find a issue about that. I
would be interested if there is some kind of plan to implement a
solution and how it should look like such that, meanwhile, i can hack
it into guice.

ML

Bob Lee

unread,
Aug 12, 2007, 6:42:15 PM8/12/07
to google...@googlegroups.com
On 8/12/07, big bad joe <jov...@gmail.com> wrote:
unfortunately I have more then one decorator for a class, you can
imagine that your solution is not really applicable in that case.

Do you mean you decorate the decorators? Why not apply them all in a custom provider?

Or, do you use different decorators in different contexts? In that case, you'd have to use annotations or some custom logic to determine which decorator to use.

I've found that concrete examples help in these situations.

Bob

big bad joe

unread,
Aug 13, 2007, 3:08:52 AM8/13/07
to google-guice
I decorate decorators, currently, up to four or five times. Like you
said, i could write one configurable provider that handles this
decoration for me. But, if youre adding new decorators, you will also
have to change this provider or inherit a new decorator that extends
the functionality. Currently, this leads to some overhead that i would
like to avoid, also because I want to give the end-user the ability to
add decorators without thinking too much about the surroundings.

I mean, youre right. There mostly is always a workaround for these
problems. But, its a trade-off between adding new functionality and
keeping your project api small and clear (currently Guice is very
small and clear and thats why im using it). Since there is an issue
about adding straighforward multi-binding (you can also solve this
problem with a provider) for the next version, one could think about
adding the decorator functionality.

ML

On 13 Aug., 00:42, "Bob Lee" <crazy...@crazybob.org> wrote:

Robbie Vanbrabant

unread,
Aug 13, 2007, 4:02:58 AM8/13/07
to google...@googlegroups.com
I didn't read the entire discussion, but you will always have to write some code to make this work. I don't see major maintenance problems with the Provider approach. For example, you could use the builder pattern to get the right decoration level.
bind(A.class).annotatedWith(Something.class).toProvider(DecoratorProvider.builder().A().C().X().build());
Sort of like builder/observer combined. You can even minimize the builder code you have to write (at least long term) by using a dynamic proxy for the builder. I blogged about this some time ago: http://garbagecollected.wordpress.com/2007/07/12/builder-pattern-deluxe/

Hope this helps,
Robbie

Robbie Vanbrabant

unread,
Aug 13, 2007, 4:13:17 AM8/13/07
to google...@googlegroups.com
Hmm. I guess you should tell the DecoratorProvider which class it needs to decorate. Something like DecoratorProvider.builder(A.class).C().X(), or something with an anonymous inner class callback. But you get the point.

Robbie

big bad joe

unread,
Aug 13, 2007, 5:00:29 AM8/13/07
to google-guice
Sorry, didnt meant to rate your comment low, it was just a "click
accident".

I dont say it is neccessary to extend the API, but it would make
things easier. Many other things that are planed for version 1.1 can
be done by workarounds ...

Anyway, your solution looks like using "static"s.

On 13 Aug., 10:02, "Robbie Vanbrabant" <robbie.vanbrab...@gmail.com>
wrote:


> I didn't read the entire discussion, but you will always have to write some
> code to make this work. I don't see major maintenance problems with the
> Provider approach. For example, you could use the builder pattern to get the
> right decoration level.
> bind(A.class).annotatedWith(Something.class).toProvider(
> DecoratorProvider.builder().A().C().X().build());
> Sort of like builder/observer combined. You can even minimize the builder
> code you have to write (at least long term) by using a dynamic proxy for the

> builder. I blogged about this some time ago:http://garbagecollected.wordpress.com/2007/07/12/builder-pattern-deluxe/186
>
> Hope this helps,
> Robbie


>
> On 8/13/07, big bad joe <jov...187@gmail.com> wrote:
>
>
>
> > I decorate decorators, currently, up to four or five times. Like you
> > said, i could write one configurable provider that handles this
> > decoration for me. But, if youre adding new decorators, you will also
> > have to change this provider or inherit a new decorator that extends
> > the functionality. Currently, this leads to some overhead that i would
> > like to avoid, also because I want to give the end-user the ability to
> > add decorators without thinking too much about the surroundings.
>
> > I mean, youre right. There mostly is always a workaround for these
> > problems. But, its a trade-off between adding new functionality and
> > keeping your project api small and clear (currently Guice is very
> > small and clear and thats why im using it). Since there is an issue
> > about adding straighforward multi-binding (you can also solve this
> > problem with a provider) for the next version, one could think about
> > adding the decorator functionality.
>
> > ML
>

> > On 13 Aug., 00:42, "Bob Lee" <crazy...189@crazybob.org> wrote:

Robbie Vanbrabant

unread,
Aug 13, 2007, 5:21:18 AM8/13/07
to google...@googlegroups.com
They're non-statics in disguise. Fooled you!
The builder method would actually be a static factory method and returns a builder object. But that's not too bad.
Perhaps you could illustrate how you would solve this problem in a future version of Guice.

Robbie

big bad joe

unread,
Aug 13, 2007, 6:21:59 AM8/13/07
to google-guice
When youre looking at the example from above i would prefer a syntax
that looks like this:

bind(A.class).to(B.class);
bind(A.class).asDecorator().to(C.class);

@Inject A a; // injects a B decorated with C


On 13 Aug., 11:21, "Robbie Vanbrabant" <robbie.vanbrab...@gmail.com>
wrote:


> They're non-statics in disguise. Fooled you!
> The builder method would actually be a static factory method and returns a
> builder object. But that's not too bad.
> Perhaps you could illustrate how you would solve this problem in a future
> version of Guice.
>
> Robbie
>

> On 8/13/07, big bad joe <jov...264@gmail.com> wrote:
>
>
>
> > Sorry, didnt meant to rate your comment low, it was just a "click
> > accident".
>
> > I dont say it is neccessary to extend the API, but it would make
> > things easier. Many other things that are planed for version 1.1 can
> > be done by workarounds ...
>
> > Anyway, your solution looks like using "static"s.
>

> > On 13 Aug., 10:02, "Robbie Vanbrabant" <robbie.vanbrab...266@gmail.com>


> > wrote:
> > > I didn't read the entire discussion, but you will always have to write
> > some
> > > code to make this work. I don't see major maintenance problems with the
> > > Provider approach. For example, you could use the builder pattern to get
> > the
> > > right decoration level.
> > > bind(A.class).annotatedWith(Something.class).toProvider(
> > > DecoratorProvider.builder().A().C().X().build());
> > > Sort of like builder/observer combined. You can even minimize the
> > builder
> > > code you have to write (at least long term) by using a dynamic proxy for
> > the
> > > builder. I blogged about this some time ago:

> >http://garbagecollected.wordpress.com/2007/07/12/builder-pattern-delu...267
>
> > > Hope this helps,
> > > Robbie


>
> > > On 8/13/07, big bad joe <jov......268@gmail.com> wrote:
>
> > > > I decorate decorators, currently, up to four or five times. Like you
> > > > said, i could write one configurable provider that handles this
> > > > decoration for me. But, if youre adding new decorators, you will also
> > > > have to change this provider or inherit a new decorator that extends
> > > > the functionality. Currently, this leads to some overhead that i would
> > > > like to avoid, also because I want to give the end-user the ability to
> > > > add decorators without thinking too much about the surroundings.
>
> > > > I mean, youre right. There mostly is always a workaround for these
> > > > problems. But, its a trade-off between adding new functionality and
> > > > keeping your project api small and clear (currently Guice is very
> > > > small and clear and thats why im using it). Since there is an issue
> > > > about adding straighforward multi-binding (you can also solve this
> > > > problem with a provider) for the next version, one could think about
> > > > adding the decorator functionality.
>
> > > > ML
>

> > > > On 13 Aug., 00:42, "Bob Lee" <crazy......269@crazybob.org> wrote:

Dhanji R. Prasanna

unread,
Aug 13, 2007, 6:45:52 AM8/13/07
to google...@googlegroups.com
On 8/13/07, Robbie Vanbrabant <robbie.v...@gmail.com > wrote:
They're non-statics in disguise. Fooled you!
The builder method would actually be a static factory method and returns a builder object. But that's not too bad.

Yea nothing wrong with that. A static bootstrap of a builder is kosher in my book.
I use it all over warp and managed to sneak it in all over Jsr311 too ;)

Dhanji.

Robbie Vanbrabant

unread,
Aug 13, 2007, 6:53:40 AM8/13/07
to google...@googlegroups.com
So thats something like
bind(A.class).toProvider(DecoratorProvider.for(B.class).decoratedWith(C.class).build());

versus

bind(A.class).to(B.class);
bind(A.class).asDecorator().to(C.class);

versus AOP, which isn't a bad choice either (at least not for the example given).
I'm not convinced that we should add this. I guess time will tell.

Robbie
Reply all
Reply to author
Forward
0 new messages