2012-07-03 4 views
2

J'essaye de construire une lib simple pour la persistance avec guice persist et d'autres choses.Générique Bind avec Guice

J'ai déjà un AbstractDao<T>, que je peux facilement étendre et lier l'implémentation concrète comme un boss.

Mais, je veux une sorte de GenericDao, comme ceci:

public abstract class GenericDao<T extends Bean> { 


@Inject 
private Provider<EntityManager> emp; 

protected EntityManager em() { 
    return emp.get(); 
} 

public AbstractDao() { 
} 

protected abstract Class<T> clazz(); 
// .... 

Et si j'aurai juste le CRUD (mis en œuvre dans dao abstrait) dans pour certains haricots, je veux injecter GenericDao<SomeBean> comme un patron .

Alors, j'ai commencé à essayer quelques hacks, et obtenir les suivantes:

public abstract class AbstractPersistentModule extends AbstractModule { 

    protected <T extends Bean> LinkedBindingBuilder<T> bindGenericDao(final Class<T> clazz) { 
     return bind(
       new TypeLiteral<GenericDao<T>>(){} 
     )./* what the hell can I do here? */; 
    } 
} 

Si je peux le faire fonctionner, je serai capable de faire un simple:

bindGenericDao(Pessoa.class); 

Quelqu'un savoir un moyen de le faire?

+0

On ne sait pas d'où vient la véritable implémentation. Pourriez-vous clarifier la question? –

+0

c'est le problème, dans ce cas, l'impl réel fournirait juste la 'Classe ', donc, j'essaye de le faire en temps d'exécution en quelque sorte ... – caarlos0

+0

Mais comment votre classeur sait quelle classe étend 'GenericDao ' une manière concrète? C'est mon point ... même si vous connaissiez complètement T, nous ne serions toujours pas au courant d'une implémentation. –

Répondre

2

Voir ce post pour une implémentation de travail.

+0

fondamentalement c'est ce que j'ai fait .. merci quand même. – caarlos0

1

Je me souviens que la soudure est une autre façon de le faire, vous pouvez utiliser pour dire le type d'élément injecté de la @ InjectionPoint ..

class Foo { 
    @Inject 
    private GenericDAO<Employee> dao; 
    //... 
} 

.. 
@Produces 
public GenericDAO<T> createDaoInstances(InjectionPoint type){ 
    return new GenericDAO(type.getMember().getSomeThing()); 
} 

public GenericDAO<T>{ 
    //.. 
    public GenericDAO<T>(EntityManager em){ 
    //... 
} 

}

Je pense que c'est un plus intéressant, juste parce que vous pouvez mieux séparer la liaison entre les composants et les couches.

+0

Si je ne me trompe pas, guice n'a pas un comportement 'InjectionPoint' comme ça ... c'est triste, une implémentation comme votre exemple sera beaucoup plus simple et plus propre ... merci quand même – caarlos0

+0

Oui caarlos0, mais vous ne pouvez pas créer un usine de fabricant pour EntityManager et spécifier sur les constructeurs DAO .. serait plus élégant et simple. –