Reputation: 4965
I asked (and answered) the same question for Dagger 1 here. How would I do something similar for Dagger 2, now that ObjectGraph.inject
no longer exists.
This question could be generalized to:
How do you do members injection if the object must be created by a different framework? (in this case, a Servlet container).
Upvotes: 22
Views: 1842
Reputation: 96
Though I am not very happy with this as I have to write boilerplate code, something like this works with servlet.
public class MyServlet extends HttpServlet {
@Inject
MyService service;
@Override
public void init( ServletConfig config ) throws ServletException {
super.init(config);
this.service = MyDaggerComponent.create().injectMyService();
}
}
You can consider setting the MyDaggerComponent instance into ServletContext and then get it like this in init() method:
((MyDaggerComponent)config.getServletContext().getAttribute("MyDaggerComponent")).injectMyService()
Upvotes: 0
Reputation: 96
I've been trying to answer this same question. I think I've gotten close to how it "should" work ideally, but I'm just derping around the GitHub project and trying to figure it out based upon scraps of information there, as a lot of the documentation for Dagger 2 is still being written (as of this week).
My example code below is actually for an Android Activity, but I believe this same approach should work for the servlet you're asking about.
Add a MembersInjector<...> to your @Component interface; for example, in the below component I've added one for my MainActivity class:
package ...;
import javax.inject.Singleton;
import dagger.Component;
import dagger.MembersInjector;
@Singleton
@Component(modules = { PlaygroundModule.class })
public interface MainComponent {
Wizard createWizard();
MembersInjector<MainActivity> mainActivityInjector();
}
And then in your class that you want to be member-injected, at an appropriate place after object creation but before you need to use your injected members, you need to create the component and use the member injection:
package ...;
// other imports
import javax.inject.Inject;
import dagger.MembersInjector;
public class MainActivity extends ActionBarActivity {
@Inject
Wizard wizard;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MainComponent c = DaggerMainComponent.create();
c.mainActivityInjector().injectMembers(this);
// other code...
}
}
The one thing I'm not clear on is whether this pattern of creating the component inside the object that's supposed to be injected into is correct. It doesn't quite feel right, but, it's still very flexible since you're only binding tightly to the component and not the modules. So perhaps this is the correct approach, but perhaps it's a bit off.
Upvotes: 8