On Thu, Oct 16, 2014 at 7:19 PM, Kevin Burton <burtona...@gmail.com> wrote:

> I humbly propose that these concepts are rather confusing in Guice
>
> @Provides vs Providers
>
> They both use similar mechanisms... IE providing the value of an object,
> but they do it differently and the semantics are confusing.
>

Here's one way to think about it:

@Provides appears *only *when configuring bindings with a Module.
Annotating a Module method with @Provides -- and possibly some scoping
annotation -- sets up a binding that means "this method is how to provide
an instance of the return type (in the specified scope, if any)". You won't
see it in regular code. It's a very convenient shorthand for something that
can be accomplished more clumsily with explicit calls to bind() and custom
providers.

Provider<T> mainly shows up at injection points in regular code. (Another
place you'll see it is as the supertype of a custom provider, but many of
those cases can be expressed more simply with @Provides.) At an injection
point, it means "instead of injecting a T directly, I'm giving you a way to
get() an instance of T". It doesn't promise any more than that. In
particular, it doesn't mean that you'll get a new instance of T every time
you call get() -- though you might.



> So when I see Provider<Foo> ... I don't know if that call is potentially
> expensive the first time.
>
I also don't know if I'm going to get one object (a singleton) or lots of
> them.
>
Or if it's a rather simple object to instantiate it's just that we're doing
> so lazily.
>

All correct, but you typically won't be presented with a Provider<Foo> in
the wild; *you'll *be writing code that needs to be injected with a Foo,
and *you'll* know of some reason that you want to defer provision of the
Foo to some point under your control *after *the injection point -- and it
could be for any of the three things you mention, or for something like
circularity -- that's when you'll use Provider<Foo> instead.

If you *do *find yourself facing a Provider<Foo> at an injection point, you
should assume that the person who put it there wants to defer the provision
of a Foo until one is actually needed, at which point you call get(). It's
also safe to assume that you should call get() every time you need a Foo in
the context of the injection point. If it's bound as a singleton, no harm
done; if it's bound in some other kind of scope (or unscoped) you'll be
making sure that you're getting a correctly-scoped instance.

--tim

-- 
You received this message because you are subscribed to the Google Groups 
"google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to google-guice+unsubscr...@googlegroups.com.
To post to this group, send email to google-guice@googlegroups.com.
Visit this group at http://groups.google.com/group/google-guice.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/google-guice/CA%2BF8eeS%3DH5GoLqciM1Hjg4M1NLgY1QoaehUToWzy0fZLSAcfiA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to