On Thu, Nov 4, 2010 at 1:00 PM, Philippe Beaudoin <
[email protected]> wrote:
> Just to come back on one of my questions: is injection automatically
> performed on the fields and methods of instances bound with
> toInstance()?
>
Yup, injection is automatically performed on fields & methods for providers
(provided they are bound as toProvider(..)).
>
> Thanks for pointing out the MembersInjector. In this case I don't
> think I can use it however, for two reasons. Tell me if I'm wrong:
> 1) My SpyProvider is generic, so I would need to inject a
> MembersInjector<T>. Would this work?
>
Yup! It's a pretty neat feature. Another thing you can do is inject a
TypeLiteral<T> if you have any need to inspect details of T at runtime.
> 2) I instantiate T using its @Inject constructor if present, so I need
> to be able to instantiate T's dependencies that appear only in the
> constructor parameter list. I don't think these dependencies can be
> instantiated with the MembersInjector?
>
MembersInjector will only replace the need to call injector.injectMembers
(replacing it with membersInjector.injectMembers). If you want to replace
the injector.getInstance(..) calls for constructor dependencies, you would
have to iterate through the dependencies in SpyProvider's constructor and
could call binder().getProvider(dependency.getKey()) for each dependency,
then call provider.get() for each and construct your instance with those.
But!... you may want to look into toConstructor bindings, which may obviate
the whole need for any of this. An example:
bind(Foo.class).annotatedWith(Internal.class).toConstructor(InjectionPoint.forConstructorOf(FooImpl.class).getMember());
bind(Foo.class).toProvider(new
SpyProvider<Foo>(getProvider(Key.get(Foo.class, Internal.class)));
class SpyProvider<T> {
private final Provider<T> internalProvider;
SpyProvider(Provider<T> p) {
this.internalProvider = p;
}
T get() {
return spy(internalProvider.get());
}
}
sam
>
> I invite you to look at the code linked with the previous post to see
> more details. SpyProvider is a relatively small class.
>
> Cheers,
>
> Philippe
>
>
> Regarding the MembersInjector, do you suggest replacing this:
>
> public class AbcProvider implements Provider<Abc> {
> MembersInjector
>
>
>
> On Thu, Nov 4, 2010 at 2:25 AM, Sam Berlin <[email protected]> wrote:
> > Yup, Providers are automatically injected too. But, injecting the
> > "Injector" is considered bad behavior. A little-known but surprisingly
> > useful interface called MembersInjector will better do what you want.
> You
> > can change your Provider to inject a MembersInjector<T> into your
> Provider
> > and then call membersInjector.injectMembers(instance). That way your
> > provider is dependent just on the dependencies of T and not on everything
> in
> > the Injector.
> >
> > sam
> >
> > On Thu, Nov 4, 2010 at 1:57 AM, PhilBeaudoin <
> [email protected]>
> > wrote:
> >>
> >> I just did something and was surprised to see it work, so I thought of
> >> posting it here to see if I could consistently rely on that behavior.
> >>
> >> I bind some class to a provider instance as such:
> >>
> >> bind(klass).toProvider(new SpyProvider(TypeLiteral.get(klass)));
> >>
> >> I need to have access to the Injector within SpyProvider so I @Inject
> >> it in a field:
> >>
> >> public class SpyProvider<T> implements Provider<T> {
> >> @Inject private Injector injector;
> >> ...
> >> }
> >>
> >> What I wanted to do at that point was to first create the injector and
> >> then use injector.injectMembers(spyProvider) to fill-in the @Inject
> >> field. I thought I needed that extra step since SpyProvider is
> >> instantiated via new and should therefore not participate
> >> automatically in dependency injection.
> >>
> >> However, I was surprised to see I could skip the injectMember() step
> >> and the injected field would be automatically filled-in by Guice after
> >> the call to Guice.createInjector(). Is this behavior expected and
> >> documented? Can I rely on it? Does it happen only for providers or is
> >> it also applied to toInstance() bindings?
> >>
> >> If you're curious about the codebase where this come from, it is from
> >> the Jukito testing framework. The above lines are from:
> >>
> >>
> http://code.google.com/p/jukito/source/browse/src/main/java/org/jukito/TestModule.java#82
> >> and
> >>
> >>
> http://code.google.com/p/jukito/source/browse/src/main/java/org/jukito/SpyProvider.java
> >>
> >> Cheers,
> >>
> >> Philippe
> >>
> >> --
> >> You received this message because you are subscribed to the Google
> Groups
> >> "google-guice" group.
> >> To post to this group, send email to [email protected].
> >> To unsubscribe from this group, send email to
> >> [email protected]<google-guice%[email protected]>
> .
> >> For more options, visit this group at
> >> http://groups.google.com/group/google-guice?hl=en.
> >>
> >
> > --
> > You received this message because you are subscribed to the Google Groups
> > "google-guice" group.
> > To post to this group, send email to [email protected].
> > To unsubscribe from this group, send email to
> > [email protected]<google-guice%[email protected]>
> .
> > For more options, visit this group at
> > http://groups.google.com/group/google-guice?hl=en.
> >
>
> --
> You received this message because you are subscribed to the Google Groups
> "google-guice" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected]<google-guice%[email protected]>
> .
> For more options, visit this group at
> http://groups.google.com/group/google-guice?hl=en.
>
>
--
You received this message because you are subscribed to the Google Groups
"google-guice" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/google-guice?hl=en.