Ask Dagger 2 to inject members of multiple instances

307 views
Skip to first unread message

baskwo nicolas

unread,
May 28, 2017, 5:07:36 PM5/28/17
to Dagger Discuss
Hi,
In my application, I'm trying to change Google Guice with Dagger 2 for performance.
I made a Module that generate new instances before the application run and save it to a class that I provide to Dagger 2.
The thing is I would need to injectMembers of every instance.
Is it possible? In Guice I was able to do injector.requestInjection(instance) or injector.injectMembers(instance).
Thanks

baskwo

Christian Gruber

unread,
Jun 8, 2017, 6:04:41 PM6/8/17
to Dagger Discuss
I'm not sure what you mean by "made a module that generate new instances" - but if your question is about the equivalent of injectMembers(instance), that is possible in dagger.

When you create a component, you can create two kids of methods - accessors or "component provider methods" like this:

@Component(modules=...)
interface MyComponent {
  Foo getFoo();
}

and that will generate new Foos (or one foo if it's scoped).

However, you have an instance, so you just want to inject its dependencies after construction. For that, you can create a members-injection method, which can have one and only one parameter - hte concrete type of the type you want to inject, like this:

@Component(modules=...)
interface MyComponent {
  void injectFoo(Foo foo);
}

...
Foo foo = new Foo();
myComponent.injectFoo(foo)

One important thing - make sure you use the most concrete type in your injection method - dagger analyses the graph at compile-time, and generates the backing code only from what it sees at compile-time. So if you have Bar which inherits from Foo, but don't tell your component about Bar, only the Foo-specific methods will be injected. For instance.

class Foo {
  @Inject SomeObject someObject;
}

class Bar extends Foo{
  @Inject OtherObject otherObject;
}

@Component(modules=...)
interface MyComponent {
  void injectFoo(Foo foo);
}

...
Bar bar = new Bar();
myComponent.injectFoo(bar);
bar.otherObject.doSomething(); // This will throw an NPE


in the above case, MyComponent only knows about Foo, and will only build logic to inject Foo. Bar is a Foo, true, but Dagger only knows about it's "Foo nature", not it's Bar extensions.  To correct this, you will need to do:

@Component(modules=...)
interface MyComponent {
  void injectBar(Bar bar);
}

So yes, members-injection is entirely possible and part of dagger's design. 

Christian

--
You received this message because you are subscribed to the Google Groups "Dagger Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dagger-discus...@googlegroups.com.
To post to this group, send email to dagger-...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages