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.
Cheers, Robin.
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.
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.)
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.
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.
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.
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.