Guice version: 2.0
My steps:
1) Create the interface Builder and it's implementation BuilderImpl
annotated with @Singleton
interface Builder {}
@Singleton
static class BuilderImpl implements Builder {}
2) Create the interface Manager and it's implementation ManagerImpl
annotated with @Singleton which depends on Builder (constructor
injection)
interface Manager {
Builder getBuilder();
}
@Singleton
static class ManagerImpl implements Manager {
final Builder builder;
@Inject
ManagerImpl(Builder builder) {
this.builder = builder;
}
public Builder getBuilder() {
return builder;
}
}
3. Create class InfoPane which depends on Manager.
static class InfoPane {
final Manager manager;
@Inject
InfoPane(Manager manager) {
this.manager = manager;
}
}
4. Let's define 2 different instance of InfoPane in test app, every
instance will have own instance of Manager, manager instance will have
own builder instance. Will use private modules and binding with
annotations:
Injector inj = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
install(new PrivateModule() {
protected void configure() {
bind(Builder.class).to(BuilderImpl.class);
bind(Manager.class).to(ManagerImpl.class);
bind(InfoPane.class).annotatedWith(Names.named
("first")).to(InfoPane.class);
expose(InfoPane.class).annotatedWith
(Names.named("first"));
}
});
install(new PrivateModule() {
protected void configure() {
bind(Builder.class).to(BuilderImpl.class);
bind(Manager.class).to(ManagerImpl.class);
bind(InfoPane.class).annotatedWith(Names.named
("second")).to(InfoPane.class);
expose(InfoPane.class).annotatedWith
(Names.named("second"));
}
});
}
});
5. Let's get instances of "first" InfoPane and "second" and check that
they have different instances of Manager in spite of @Singleton
annotations:
InfoPane firstPane = inj.getInstance(Key.get(InfoPane.class,
Names.named("firstPane")));
InfoPane secondPane = inj.getInstance(Key.get(InfoPane.class,
Names.named("secondPane")));
final Manager firstManager = firstPane.manager;
final Manager secondManager = secondPane.manager;
System.out.printf("Are managers the same = %s\n",
firstManager.equals(secondManager));
It's ok, both managers are different instances of ManagerImpl class.
6. Let's check that firstManager builder is not the same instance of
secondManager builder:
System.out.printf("Are builders the same = %s\n",
firstManager.getBuilder().equals(secondManager.getBuilder()));
Upps, firstManager.getBuilder() is the same as secondManager.getBuilder
(), it's one instance of BuilderImpl.
But as I can understand, they must be the different object, in spite
of @Singleton, because they binded in different private modules.
It's looks like a bug.
Full test here http://pastie.org/486289
I tested it with binding in scope (bind(Builder.class).to
(BuilderImpl.class).in(Scopes.SINGLETON)), it's work the same.
I increased dependency hierachy deep (Builder depends on Foo and
FooImpl(@Singleton)), it's work the same.
Original issue reported on code.google.com by aleksey....@gmail.com on 22 May 2009 at 11:21
Original issue reported on code.google.com by
aleksey....@gmail.com
on 22 May 2009 at 11:21