Binding without interfaces

4,898 views
Skip to first unread message

Jon Vaughan

unread,
Nov 7, 2009, 3:58:43 PM11/7/09
to google-guice
Hi,

I'm new to Guice, so I apologise if this is a stupid question, or if
my I'm just plain wrong. I'm trying to retrofit it to a large
existing codebase.

My understanding is that if I have a Guice binding like:

bind(MyInterface.class).to(MyClass.class)

where MyClass implements MyInterface and has a constructor like:

@Inject
public myClass(AnotherClass somethingElse)
{
//..blah
}

then when Guice supplies an instance of MyClass, that instance will
have been injected with, in turn, an AnotherClass instance, providing
that is also bound (hopefully I'm right so far?)

So now imagine that MyClass does NOT implement MyInterface (classes in
my codebase only implement interfaces where there are multiple
implementations of that interface) .

Guice does not permit me to do this:

bind(MyClass.class).to.(MyClass.class)

And this is not the same thing:

bind(MyClass.class).toInstance(new MyClass())

because that instance will not have been supplied with an
AnotherClass.

I could have some sort of bootstrap where I:

bind(AnotherClass.class).toInstance(new AnotherClass());

and then

Injector injector = Guice.createInjector(getBootstrapModule());
bind(MyClass.class).toInstance(injector.getInstance(MyClass.class));

but then I'm stumped if I want to then inject both MyClass and
AnotherClass into something, unless I can live with multiple instances
of AnotherClass.

I do not want to write interfaces for these classes just so I can
inject them; have I got something wrong here, or is there a way around
this?

Many thanks if you are able to help

Jon

dg

unread,
Nov 7, 2009, 6:01:39 PM11/7/09
to google-guice
just

bind(MyClass.class);

-d

Jon Vaughan

unread,
Nov 7, 2009, 6:09:19 PM11/7/09
to google-guice
Aha, nice one. That wasn't mentioned (well, there was no example
like that) on http://code.google.com/p/google-guice/wiki/Bindings),
which was why I was confused.

Thanks for the speedy response

J

Christian Edward Gruber

unread,
Nov 7, 2009, 6:35:57 PM11/7/09
to google...@googlegroups.com
I've added the example to the documentation at:

http://code.google.com/p/google-guice/wiki/LinkedBindings

Christian.

Maaartin

unread,
Nov 7, 2009, 6:54:29 PM11/7/09
to google...@googlegroups.com
Jon Vaughan wrote:
> Hi,
>
> I'm new to Guice, so I apologise if this is a stupid question, or if
> my I'm just plain wrong. I'm trying to retrofit it to a large
> existing codebase.
>
> My understanding is that if I have a Guice binding like:
>
> bind(MyInterface.class).to(MyClass.class)
>
> where MyClass implements MyInterface and has a constructor like:
>
> @Inject
> public myClass(AnotherClass somethingElse)
> {
> //..blah
> }
>
> then when Guice supplies an instance of MyClass, that instance will
> have been injected with, in turn, an AnotherClass instance, providing
> that is also bound (hopefully I'm right so far?)
>
> So now imagine that MyClass does NOT implement MyInterface (classes in
> my codebase only implement interfaces where there are multiple
> implementations of that interface) .
>
> Guice does not permit me to do this:
>
> bind(MyClass.class).to.(MyClass.class)

You do not need it, this is a sort of default.
I'd say, wrinting only
bind(MyClass.class);
does what you wanted.

> And this is not the same thing:
>
> bind(MyClass.class).toInstance(new MyClass())
>
> because that instance will not have been supplied with an
> AnotherClass.

Right. Generelly, I try to avoid bind-toInstance.
In the case above annotating MyClass with @Singleton or using simply
bind(MyClass.class).asEagerSingleton()
or maybe
bind(MyClass.class).in(Scopes.SINGLETON);
may be better (I supose you want a singleton since you get one using bind-toInstance).

> I could have some sort of bootstrap where I:
>
> bind(AnotherClass.class).toInstance(new AnotherClass());
>
> and then
>
> Injector injector = Guice.createInjector(getBootstrapModule());
> bind(MyClass.class).toInstance(injector.getInstance(MyClass.class));
>
> but then I'm stumped if I want to then inject both MyClass and
> AnotherClass into something, unless I can live with multiple instances
> of AnotherClass.

I think this could be solved using child injectors but this is currently too high for me.

> I do not want to write interfaces for these classes just so I can
> inject them; have I got something wrong here, or is there a way around
> this?

You need no interfaces for this. Generally, you can use abstract or concrete superclass instead of interface, and you need nothing if there's no hierarchy.

> Many thanks if you are able to help

Regards, Maaartin.

Moandji Ezana

unread,
Nov 7, 2009, 6:49:05 PM11/7/09
to google...@googlegroups.com
On Sun, Nov 8, 2009 at 12:01 AM, dg <gil...@gmail.com> wrote:

just

bind(MyClass.class);


Do you even have to do that? I thought JIT bindings were created when none existed, as long as you have a no-arg constructor or inject classes that are either bound or also have a no-arg constructor.

Here are two JUnit test I wrote to try this out:
    
    @Test
    public void inject_no_arg_constructor_without_binding() {
        Injector injector = Guice.createInjector();
        TestEntity instance = injector.getInstance(TestEntity.class);
        assertNotNull(instance);
    }
    
    @Test
    public void inject_one_arg_constructor_that_takes_TestEntity_without_binding() {
        Injector injector = Guice.createInjector();
        InjectedEntity injectedEntity = injector.getInstance(InjectedEntity.class);
        assertNotNull(injectedEntity);
        assertNotNull(injectedEntity.testEntity);
    }

Like Jon Vaughan, I'm also fairly new to Guice. Why is this considered bad practice, if the interface would not raise the level of abstraction?

And is there a difference between bind(MyClass.class) and not binding at all?

Moandji

dg

unread,
Nov 10, 2009, 12:56:38 AM11/10/09
to google-guice
bind( MyClass.class ) is 100% optional.

I do it, but them I'm pedantic about things.

-d

Brian Pontarelli

unread,
Nov 10, 2009, 10:29:51 AM11/10/09
to google...@googlegroups.com
It is required if you want to ask Guice about what is bound. I use it
to help find classes that implement things.

-bp
Reply all
Reply to author
Forward
0 new messages