Glide
Glide

Reputation: 21255

Difference between bind(Foo.class).to(Bar.class) vs bind(Foo.class).toInstance(new Bar())

What's the difference between bind(Foo.class).to(Bar.class) and bind(Foo.class).toInstance(new Bar());

Also, would fields be injected properly with the latter method of calling the constructor new Bar()?

Upvotes: 1

Views: 3167

Answers (1)

Jeff Bowman
Jeff Bowman

Reputation: 95704

bind(Foo.class).to(Bar.class) is a linked binding: you're telling Guice "whenever someone asks for a Foo, give them a Bar instead". You're not telling Guice how to create a Bar; this implies that there's an @Inject-annotated or public zero arg constructor and that you're allowing Guice to do everything it normally does including field injection. You're also not telling Guice whether to memoize the Bar instance and keep it around, meaning it will create a new Bar every time. (Note that this doesn't preclude you from bind(Bar.class).to(Baz.class) or bind(Bar.class).toInstance(new Baz()) if you wanted to; without one of those you're technically letting Bar be an implicit or JIT binding.)

bind(Foo.class).toInstance(new Bar()) is an instance binding. You're telling Guice "whenever someone asks for a Foo, give them this Bar instead". Guice doesn't ever try to create a Bar, so it doesn't try to inject constructor parameters, and it also doesn't ever try to create a different Bar: you always get the same one. UPDATE: Thanks Tavian, I'd forgotten that automatic injections do allow field injection on toInstance bindings. Note that none of this affects injection requests for Bar, just Foo.

So, the former allows injection and creates a new instance every time, and the latter lets you create instances manually and returns the same instance every time. Those can also be two separate decisions:

  • To always return the same instance, you can mark the class with @Singleton, or make your binding .in(Singleton.class). See Scopes for more details and options. Guice creates the instance, so you have access to field injections.
  • To let you create instances manually without field injection (but allowing for calls to static factory methods or custom initializer methods), bind to a Provider or create a @Provides method. Guice won't inject fields, because you've taken the creation on yourself.

    Those provider/@Provides bindings can also be made Singleton, which is similar to toInstance above, but doesn't require you to create your instance at injector creation time.

Upvotes: 14

Related Questions