wulfgarpro
wulfgarpro

Reputation: 6934

How to inject with Guice `Module` where constructor accepts Class?

The title describes my problem.

E.g.

public class EntryDAOModule extends AbstractModule {

    @Override
    protected void configure() {
        bind(EntryDAO.class).to(EntryDTOMongoImpl.class); // what should this be?       
    }
}

As shown, what should be the parameter to .to, given the below:

public class GenericDAOMongoImpl<T, K extends Serializable> extends BasicDAO<T, K> {
    public GenericDAOMongoImpl(Class<T> entityClass) throws UnknownHostException {
        super(entityClass, ConnectionManager.getDataStore());
    }
}

public class EntryDAOMongoImpl extends GenericDAOMongoImpl<EntryDTOMongoImpl, ObjectId> implements EntryDAO<EntryDTOMongoImpl> {
    private static final Logger logger = Logger.getLogger(EntryDAOMongoImpl.class);

    @Inject
    public EntryDAOMongoImpl(Class<EntryDTOMongoImpl> entityClass) throws UnknownHostException {
        super(entityClass);
    }
    ...
}

How can I instantiate the EntryDAOMongoImpl class like so:

Injector injector = Guice.createInjector(new EntryDAOModule());
this.entryDAO = injector.getInstance(EntryDAO.class); // what should this be?

Upvotes: 2

Views: 2546

Answers (1)

John Ericksen
John Ericksen

Reputation: 11113

What you are going to need here is to create a factory. Using assisted injection can help you here.

You can see my previous post regarding assisted injection

but here's the exact solution for your case:

EntryDAOMongoImpl:

public class EntryDAOMongoImpl extends GenericDAOMongoImpl<EntryDTOMongoImpl, ObjectId> implements EntryDAO<EntryDTOMongoImpl> {
    private static final Logger logger = Logger.getLogger(EntryDAOMongoImpl.class);

    @Inject
    public EntryDAOMongoImpl(@Assisted Class<EntryDTOMongoImpl> entityClass) throws UnknownHostException {
        super(entityClass);
    }
    ...
}

Factory:

public interface EntryDAOFactory {
    public EntryDAOMongoImpl buildEntryDAO(Class<EntryDTOMongoImpl> entityClass);
}

Module:

public class EntryDAOModule extends AbstractModule {

    @Override
    protected void configure() {
        //bind(EntryDAO.class).to(EntryDAOMongoImpl.class); // what should this be?

        FactoryModuleBuilder factoryModuleBuilder = new FactoryModuleBuilder();
        install(factoryModuleBuilder.build(EntryDAOFactory.class));
    }
}

Usage:

Injector injector = Guice.createInjector(new EntryDAOModule());
EntryDAOFactory factory = injector.getInstance(EntryDAOFactory.class);
this.entryDAO = factory.buildEntryDAO(entityClass);

If you are going to be using the EntryDAOMongoImpl as a singelton (natural usage of a singleton imo) then you can do the following without assisted injection within your module:

public class EntryDAOModule extends AbstractModule {

    @Override
    protected void configure() {
        EtnryDTOMongoImpl dto = new EntryDTOMongoImpl(TargetEntry.class); //guessing here
        bind(EntryDAO.class).toInstance(new EntryDAOMongoImpl(dto)); // singleton   
    }
}

Let me know if that helps

Upvotes: 2

Related Questions