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.