Any way to override bindings?

6,641 views
Skip to first unread message

Ben

unread,
Mar 16, 2007, 11:45:24 PM3/16/07
to google...@googlegroups.com
Hi there.

We have a parent project and a child project. The child project is a
customization of the parent project, where some of the interfaces in
parent project will have different implementation classes.


What I was thinking that we could do was to subclassing a Module as:

parent project:

class MyModule extends AbstractModule {
protected void configure() {
bind(Interface1.class).to(Class1.class);
bind(Interface2.class).to(Class2.class);
...
}
}

child project:
class SubModule extends MyModule {
protected void configure() {
super.configure();
bind(Interface2.class).to(Subclass2.class);
}
}

This way I'm hoping that sub module will use almost every setting in
parent project with the implementation class of Interface2 changed to
Subclass2.

But if I'm not mistaken, Guice isn't happy about this. An interface
can only have one bindings.


I'm trying to think of a workaround or a better solution. At the same
time, hope some of you guys may shed some light for me.

Ben.

Robin Sheat

unread,
Mar 17, 2007, 12:16:46 AM3/17/07
to google-guice
On Mar 17, 4:45 pm, Ben <ajoo.em...@gmail.com> wrote:
> I'm trying to think of a workaround or a better solution. At the same
> time, hope some of you guys may shed some light for me.
The ability to explicitly or implicitly overwrite a binding would be
useful for me also. The way I was thinking of doing was just to have a
'base' module, and then a 'fork A' subclass and a 'fork B' subclass
with the different bindings in them, but it is a bit
less flexible.

Cheers, Robin.

Kevin Bourrillion

unread,
Mar 18, 2007, 3:22:07 AM3/18/07
to google...@googlegroups.com
We don't support overriding bindings in any way at this point.  It's nontrivial to allow this while maintaining order-independence of modules and bindings, which is very important to us.

In your case, instead of a hierarchy of modules, all you need is for your modules to be more granular.  Modules should be atomic; a grouping of bindings that an application is likely to want either all of or none of.

I hope this helps.

K

Ben

unread,
Mar 18, 2007, 9:18:14 AM3/18/07
to google...@googlegroups.com
Tough.

Theoretically I like the idea of making everything granular enough so
that no overriding is needed. That makes everything simple.

Yet practically I do not know an elegant way of doing this.

There is no rule for what the sub project can subclass or override
currently. The overriding is really adhoc, in that the owner of
sub-project can choose to customize all of the 327 interfaces the
parent project has.

The only way I can think of is to make every "bind" an individual
overidable method:

class MyModule {
protected void configure() {
configureType1();
configureType2();
...
}
void configureType1() {
bind(Type1).to(Class1);
}
void configureType2() {
bind(Type2).to(Class2);
}
}

Personally I hate this design (make everything abstract because you
never know if you need to override it). And it does end up with a lot
more code.


I can see we may be able to live with the "no default impl resolver",
but not being able to override (or an equivalent workaround) will be a
big pain for us, if not a show-stopper to my proposal of using Guice.

Ben

unread,
Mar 18, 2007, 9:52:45 AM3/18/07
to google...@googlegroups.com
I can see the value of maintaining order independence of modules. But
is it worth maintaining it for bindings within a module?

What do you think if Guice does not blow away when a binding is
overriden by the same module object that created it? Implementation of
this shouldn't be too hard ( by wrapping the Binder object with the
Module reference before passing it to the Module.configure(), and
keeping the reference of source Module in the binding.)

Message has been deleted

Ben

unread,
Mar 18, 2007, 9:12:26 PM3/18/07
to google...@googlegroups.com
Hmm. then this custom API will also need to take care of things like
annotatedWith(), as this creates different Key.

Feels like it is unavoidable to replicate some logic in Guice to make
this MyModule thing work.

Also, is custom API needed? I was thinking of a set of decorators on
Binder, LinkedBindingBuilder etc..I want to avoid telling my team
mates that: Yes, we are using Guice. But this in-house abstraction
layer on top of it is necessary because of blah blah blah.

Dhanji R. Prasanna

unread,
Mar 18, 2007, 9:24:11 PM3/18/07
to google...@googlegroups.com
On 3/19/07, Ben <ajoo....@gmail.com> wrote:

Hmm. then this custom API will also need to take care of things like
annotatedWith(), as this  creates different Key.

Feels like it is unavoidable to replicate some logic in Guice to make
this MyModule thing work.

 
Yea you will have to atleast impl the binder interface(s) or an analog of them.

Also, is custom API needed? I was thinking of a set of decorators on
Binder, LinkedBindingBuilder etc..I want to avoid telling my team
mates that: Yes, we are using Guice. But this in-house abstraction
layer on top of it is necessary because of blah blah blah.

if you impl the guice binder interfaces they wont need to know (except that you have broken the contract for modules--i.e. rebinding allowed). That ought to be made clear in any event.

Ben

unread,
Mar 18, 2007, 9:29:47 PM3/18/07
to google...@googlegroups.com
> if you impl the guice binder interfaces they wont need to know (except that
> you have broken the contract for modules--i.e. rebinding allowed). That
> ought to be made clear in any event.
>

My feeling is that we can take the "no rebinding" rule as imposed by
the default Guice Binder interface.

And we could create a RebindableBinder decorator that wraps a Binder.
And that is quite explicit.

Dhanji R. Prasanna

unread,
Mar 18, 2007, 9:37:36 PM3/18/07
to google...@googlegroups.com
On 3/19/07, Ben <ajoo....@gmail.com> wrote:

Sure, either way I suggest you impl the Binder interfaces for compatibility. and explicitly state the breaking of contract. It is not a cardinal sin to break the contract with a sub-type override if you make it clear.

java.sql.Date comes to mind.

Btw, is it only the binder that enforces the no-rebinding rule? Can we use the default impls of say AnnotatedBindingBuilder etc?

Ben

unread,
Mar 18, 2007, 9:54:45 PM3/18/07
to google...@googlegroups.com
>
> Btw, is it only the binder that enforces the no-rebinding rule? Can we use
> the default impls of say AnnotatedBindingBuilder etc?
No. have to decorate all of them.

Ben

unread,
Mar 19, 2007, 1:52:59 AM3/19/07
to google...@googlegroups.com
Just wrote an OverridableModule that allows binding overriding within
the same module.

Have to say the impl is not trivial. Used quite some dynamic proxy
tricks. (including using http://dimple.codehaus.org)

Will share it after some polishing.

Ben

unread,
Mar 19, 2007, 11:08:32 PM3/19/07
to google...@googlegroups.com
Alright. The attached is a zip file that contains the classes supporting overriding bindings.

This impl depends on http://dimple.codehaus.org to avoid versioning issue in decorating Guice interfaces such as Binder, AnnotatedBindingBuilder etc. (I could create decorators directly and generate delegate code using Eclipse, but the code will not compile should more methods are added to these interfaces in the future, which I consider quite possible.)

Anyway, by extending from OverridableModule, binding overriding is supported. The use of OverridableModule is exactly the same as AbstractModule.




On 3/19/07, Ben < ajoo....@gmail.com> wrote:
overrider.zip

Dhanji R. Prasanna

unread,
Mar 19, 2007, 11:16:45 PM3/19/07
to google...@googlegroups.com
sweet thanks for this Ben

Sergiy Sokolenko

unread,
Jan 21, 2014, 7:14:12 AM1/21/14
to google...@googlegroups.com
You can also use com.gogle.inject.util.Modules.override(Module... modules) to override bindings as suggested by @albertb at http://stackoverflow.com/questions/483087/overriding-binding-in-guice

Tim Boudreau

unread,
Feb 18, 2014, 6:44:04 AM2/18/14
to google...@googlegroups.com
I think the mention of "inheritance" at the top of this thread sent it off in some weird directions.  You don't have an inheritance problem.  You have a "one module binding orthagonal things" problem.

Split the stuff that will not be "overridden" out of your "parent module".  Create a new module - we'll call it "common" that binds that stuff.

For the remainder, have two modules, and only use one of them at runtime.  One will be your stock bindings, and the other will be your "customized" bindings.


It's really rare to need inheritance in writing Guice modules (or most anything, really);  thinking in terms of inheritance can blind one to really simple composition-based ways of solving problems.

-Tim

Reply all
Reply to author
Forward
0 new messages