im pretty new in working with dropwizard. Currently I'm trying to implement the HK2 dependency injection. That works pretty fine inside a resource but it doesn't work outside of a resource. Here is what I'm doing:
Client client = new JerseyClientBuilder(environment).using(configuration.getJerseyClientConfiguration()).build("contentmoduleservice");
//DAOs
ContentModuleDAO contentModuleDAO = new ContentModuleDAO(hibernate.getSessionFactory());
ModuleServedDAO moduleServedDAO = new ModuleServedDAO(hibernate.getSessionFactory());
//Manager
ContentModuleManager moduleManager = new ContentModuleManager();
EntityTagManager eTagManager = new EntityTagManager();
ProposalManager proposalManager = new ProposalManager(client, configuration);
environment.jersey().register(new AbstractBinder() {
@Override
protected void configure() {
bind(eTagManager).to(EntityTagManager.class);
bind(contentModuleDAO).to(ContentModuleDAO.class);
bind(moduleServedDAO).to(ModuleServedDAO.class);
bind(proposalManager).to(ProposalManager.class);
bind(moduleManager).to(ContentModuleManager.class);
}
});
I create Instance of the classes I want to be injectible and bind them.
Inside my resource the injection works:
@Api
@Path("/api/contentmodule")
public class ContentModuleResource {
static final Logger LOG = LoggerFactory.getLogger(ContentModuleResource.class);
static final int MAX_PROPOSALS_PER_MODULE = 10;
@Inject
private ContentModuleDAO contentModuleDAO;
@Inject
private EntityTagManager eTagManager;
@Inject
private ProposalManager proposalManager;
@Inject
private ContentModuleManager contentModuleManager;
All these variables are filled with an Instance of the right class.
The problem is: The ContentModuleManager should also get some of these classes via injection:
public class ContentModuleManager {
@Inject
private ContentModuleDAO contentModuleDAO;
@Inject
private ProposalManager proposalManager;
@Inject
private ModuleServedDAO moduleServedDAO;
But those are null. Can somebody explain a dropwizard noob why this happens and how I can fix this? :D
Thanks!
If you are going to instantiate the service yourself then it is not going to go through the DI lifecycle and will never be injected. You can let the container create the service if you just register the services as a class
bind(ContentModuleManager.class)
.to(ContentModuleManager.class)
.in(Singleton.class);
On the other hand, if you are creating all the services yourself and you have all of them available, why don't you just not use the DI container at all? Just pass all the services through the constructor. Whether you are using constructor injection1 or manually passing through the constructor, getting the service through the constructor is good practice anyway, as it allows for easier testing of the service.
1 - Constructor injection
private Service service;
@Inject
public OtherService(Service service) {
this.service = service;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With