How does expose() work in nested PrivateModules

2,565 views
Skip to first unread message

Andy

unread,
Apr 5, 2011, 7:55:59 PM4/5/11
to google-guice
Say in my Injector I have a PrivateModule (call it A), and A has
installed in it a PrivateModule (call it B).

Lets say in B, I call expose(Foo.class), my assumption (I'm new) is
that the binding for Foo.class is exposed to the entire Injector.

If I am wrong, I might be misinterpreting my error messages, and
disregard the rest of this.

Otherwise, Can I expose B's binding for Foo.class in a way that it
would only be available to its parent, or rather can I install A in a
way that the "exposed" bindings for B are not exposed in the root
Injector?

If this is currently not available, is it atleast possible? Could it
be added as an enhancement? Would it be a valuable enhancement?

The situation that provokes this question is, in my root Injector I
want to install a different PrivateModule(call it C), and C has it's
own exposed binding for Foo.class. The exposed binding in module B
causes a CreationException.

Perhaps my entire approach is flawed? I'm just trying to reuse
modules, maybe I just need to build modules to meet specific
situations? Thanks for your responses!

limpb...@gmail.com

unread,
Apr 5, 2011, 9:23:59 PM4/5/11
to google-guice
Exposing a binding makes it visible to the containing module and its
sibling modules. If you want to expose something nested in two layers
of private modules, you need to expose it in once at each level.

Because of awkward interations with JIT bindings, the SPI and
multibindings, PrivateModules aren't particularly awesome in practice.
Nesting them should work, but it suggests your design is more
complicated than necessary. A simpler way to do encapsulation is with
package-private classes and regular modules. On my projects we only
use PrivateModules when forced to do so.

Cheers,
Jesse

Andy

unread,
Apr 6, 2011, 1:09:06 AM4/6/11
to google-guice
I understand what your saying about PrivateModules not being ideal,
but I need to use them.

From my test code, I am unable to add bindings for the same class is
PrivateModule legs.

class A extends PrivateModule
{@Override
protected void configure() {install(new B());
}

class B extends PrivateModule
{@Override
protected void configure() {
bind(Foo.class).to(FooImpl.class);
expose(Foo.class);
}}

class C extends PrivateModule
{
@Override
protected void configure() {
bind(Foo.class).to(FooImpl.class);
expose(Foo.class);
}}


Creating an Injector with Modules A and C breaks,
i.e.
Guice.createInjector(new A(),new C());

Before I asked this question, this was basically my setup. What I
dont understand is, that I'm not exposing the Foo.class binding from
the A module, so why it is interfering with the binding in the C
module.

When you said "Exposing a binding makes it visible to the containing
module and its sibling modules.",

I thought perhaps that I could modify module A to wrap B in a
PrivateModule,
public class A extends PrivateModule{
@Override
protected void configure() {
install(new PrivateModule() {
@Override
protected void configure() {
install(new B());
}});}}

No dice though, this fails too. Any recommendations?

Fred Faber

unread,
Apr 6, 2011, 8:51:25 AM4/6/11
to google...@googlegroups.com, Andy
Top-level view:  you seem to want to configure classes within A with the Foo that is exported from B.  If A is a private module, simply install B without making B a PrivateModule.  That will make the bindings in B be visible to everything in A, but it won't export anything from B into a potential collision with bindings in C.

Similarly, at least from the simplified example, I don't know that you'd need to export Foo from C.

Fred


--
You received this message because you are subscribed to the Google Groups "google-guice" group.
To post to this group, send email to google...@googlegroups.com.
To unsubscribe from this group, send email to google-guice...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-guice?hl=en.


nino martinez wael

unread,
May 30, 2011, 11:22:23 AM5/30/11
to google...@googlegroups.com

We use private modules in conjunction with multibinder and names annotated to create a driver like framework, using a syd interface. When i have more time ill put up a blog or something somewhere.

nino martinez wael

unread,
May 30, 2011, 11:23:29 AM5/30/11
to google...@googlegroups.com

Thats a common interface not syd:)

Reply all
Reply to author
Forward
0 new messages