2016-11-17 5 views
1

Для небольшого побочного проекта, над которым я работаю, я пытался реализовать что-то из шаблона DAO для моих взаимодействий с БД и начал использовать Guice (в первый раз) для обработки DI для меня. Сейчас у меня есть этот класс иерархия:Зависимость впрыска с использованием Guice с шаблоном DAO

enter image description here

DAOImpl принимает ссылку на тип класса, так что мой клиент базы данных (Монго/морфий) может сделать некоторые инициализации работы и создать экземпляр BasicDAO предоставленного морфием. Вот фрагменты соответствующих классов:

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); 
    } 
} 

Я знаю, что мне нужно сказать Guice, чтобы связать соответствующие классы для каждого родового DAOImpl, который получает продлен, но я не уверен в том, как это сделать. Похоже, на это можно было ответить, но это не для меня. Я пробовал некоторые из следующих:

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>>() {}); 
    } 
} 

Вот некоторые из ошибок, которые я видел:

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) 

Любая помощь будет оценена.

ответ

2

Если вы хотите место инъекции, как следующее:

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

, который будет введен с экземпляром вашего UserDAO класса тогда

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

является correct syntax.

Как за другой ошибки:

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

Это потому, что Datastore является интерфейсом. Вам необходимо привязать интерфейс к реализации, экземпляру или Provider<Datastore>.

Чтобы решить, как это сделать, подумайте о шагах, которые вам нужно будет сделать вручную без дополнительного усложнения Guice. Как только вы это осознаете на 100%, вы можете попробовать и спроектировать графический объект, который соответствующим образом отражает шаги инициализации морфий.

Для начала, то morphia quick tour имеет руководство о том, как получить экземпляр Datastore объекта:

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(); 

Из своего кода, вы можете видеть, что есть по крайней мере две зависимости, необходимые, чтобы получить Datastore:

  1. одноплодной Morphia
  2. одноплодной MongoClient

Вам нужно будет написать код для его установки, возможно, используя класс Guice Provider.

+0

Эй, просто хотел отойти назад и сказать спасибо.Я начал новый старомодный путь, вручную вложив deps и проделав свой путь к решению один шаг за раз. Ваш ответ о 'TypeLiteral' доставил мне большую часть пути, но так как мой' DAO' - это интерфейс, который реализован DAOImpl', то для меня это работает: 'bind (новый TypeLiteral > () { }). До (UserDAO.class); bind (новый TypeLiteral >() { }). (PersonDAO.class); связывание (Mongo.class) .то (MongoClient.class); ' – Justin

+0

А для' Datastore', я в конечном итоге сделать поставщик, как вы предложили и с помощью '@ Singleton' аннотации: ' @Provides @Singleton public Datastore datastoreProvider (MongoClient mongoClient, Конфигурация ServerConfig) { Morphia morphia = new Morphia(); return morphia.createDatastore (mongoClient, config.getMongoConfig(). GetDatabase()); } ' – Justin

+0

@ Justin Я очень рад, что это помогло - удачи в остальной части вашего приложения! –

 Смежные вопросы

  • Нет связанных вопросов^_^