Dependency injection using Guice with the DAO pattern

别来无恙 提交于 2019-12-20 03:21:37

问题


For a small side project I'm working on I've been trying to implement something of a DAO pattern for my interactions with the DB, and have started using Guice (for my first time) to handle the DI for me. Right now I have this class hierarchy:

DAOImpl takes a reference to a class type so my database client (mongo/morphia) can do some initialization work and instantiate a BasicDAO provided by morphia. Here's snippets of the relevant classes:

public class DAOImpl<T> implements DAO<T> {
  private static final Logger LOG = LoggerFactory.getLogger(DAOImpl.class);
  private static final String ID_KEY = "id";
  private final org.mongodb.morphia.dao.DAO morphiaDAO;

  @Inject
  public DAOImpl(Datastore ds, Class<T> resourceClass) {
    morphiaDAO = new BasicDAO(resourceClass, ds);

    LOG.info("ensuring mongodb indexes for {}", resourceClass);
    morphiaDAO.getDatastore().ensureIndexes(resourceClass);
  }
}

public class UserDAO extends DAOImpl<User> {
  @Inject
  public UserDAO(Datastore ds) {
    super(ds, User.class);
  }

  public User findByEmail(String email) {
    return findOne("email", email);
  }
}

I know that I need to tell Guice to bind the relevant classes for each generic DAOImpl that gets extended, but I'm unsure of how to do it. This looks like it might have been answered but it's not clicking for me. I've tried some of the following:

public class AppInjector extends AbstractModule {
  @Override
  protected void configure() {
    bind(com.wellpass.api.dao.DAO.class).to(DAOImpl.class);

//    bind(new TypeLiteral<SomeInterface<String>>(){}).to(SomeImplementation.class);
//    bind(new TypeLiteral<MyGenericInterface<T>>() {}).to(new TypeLiteral<MyGenericClass<T>>() {});
//    bind(new TypeLiteral<DAO<User>>() {}).to(UserDAO.class);

    bind(new TypeLiteral<DAO<User>>(){}).to(new TypeLiteral<DAOImpl<User>>() {});
  }
}

These are some of the the errors I've seen:

com.google.inject.CreationException: Unable to create injector, see the following errors:

1) No implementation for org.mongodb.morphia.Datastore was bound.
  while locating org.mongodb.morphia.Datastore
    for the 1st parameter of com.wellpass.api.dao.UserDAO.<init>(UserDAO.java:12)
  at com.wellpass._inject.AppInjector.configure(AppInjector.java:18)

2) java.lang.Class<T> cannot be used as a key; It is not fully specified.
  at com.wellpass.api.dao.DAOImpl.<init>(DAOImpl.java:19)
  at com.wellpass._inject.AppInjector.configure(AppInjector.java:14)

Any help would be much appreciated.


回答1:


If you want an injection site like the following:

@Inject
public DAOConsumer(DAO<User> dao) {
}

to be injected with an instance of your UserDAO class then

bind(new TypeLiteral<DAO<User>>() {}).to(UserDAO.class);

is the correct syntax.

As for your other error:

1) No implementation for org.mongodb.morphia.Datastore was bound.

This is because Datastore is an interface. You need to bind the interface to an implementation, an instance, or a Provider<Datastore>.

To work out how to do this, think of the steps you would need to do this manually without the extra complication of Guice. Once you 100% understand this, you can try and design an object graph that appropriately reflects the steps in the initialization of morphia.

To get you started, the morphia quick tour has a guide on how to get an instance of the Datastore object:

final Morphia morphia = new Morphia();

// tell Morphia where to find your classes
// can be called multiple times with different packages or classes
morphia.mapPackage("org.mongodb.morphia.example");

// create the Datastore connecting to the default port on the local host
final Datastore datastore = morphia.createDatastore(new MongoClient(), "morphia_example");
datastore.ensureIndexes();

From their code, you can see that there are at least two dependencies required to get the Datastore:

  1. A singleton Morphia
  2. A singleton MongoClient

You will have to write some code to set this up, possibly using Guice's Provider class.



来源:https://stackoverflow.com/questions/40646780/dependency-injection-using-guice-with-the-dao-pattern

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!