Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dropwizard HK2 injection

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!

like image 347
Materno Avatar asked Feb 07 '18 11:02

Materno


1 Answers

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;
}
like image 76
Paul Samsotha Avatar answered Sep 27 '22 21:09

Paul Samsotha