Je cherche des suggestions sur la façon d'injecter des dépendances d'exécution dans les entités JPA récupérées depuis Hibernate. Mon problème est essentiellement ceci:Suggestions de motifs nécessaires (Hibernate + Guice)
J'ai un certain nombre de sous-classes différentes d'un objet de transaction. Chaque sous-classe Transaction a un comportement différent lorsqu'elle est exécutée et nécessite un ensemble différent de dépendances de l'environnement. Ces objets Transaction sont gérés en tant qu'entités JPA par Hibernate, donc je ne peux pas utiliser efficacement Guice pour l'injection de dépendance pour remplir les instances avec leurs dépendances environnementales comme je le fais dans le reste de mon application.
Pour contourner ce problème, j'ai pris une approche qui est un peu semblable au modèle des visiteurs, comme suit:
public abstract class Transaction {
// ...snip...
public abstract void apply(Transactor transactor);
}
public class TransactionA extends Transaction {
public void apply(Transactor transactor) {
transactor.execute(this);
}
}
public class TransactionB extends Transaction {
public void apply(Transactor transactor) {
transactor.execute(this);
}
}
// other Transaction subclasses with the same boilerplate
public interface Transactor {
public void execute(TransactionA trans);
public void execute(TransactionB trans);
// corresponding methods for other transaction types.
}
public class BeginTransactor {
@Inject
private Foo execAdep;
public void execute(TransactionA trans) {
execAdep.doSomething(...)
}
@Inject
private Bar execBdep;
public void execute(TransactionB trans) {
execBdep.doOther(...)
}
}
J'ai différentes implémentations de Transactor pour différentes parties du cycle de vie des transactions. Ceux-ci peuvent être injectés en utilisant la dépendance-Guice dans le contexte dans lequel je veux traiter les transactions, où j'appelle simplement:
Transactor transactor = injector.getInstance(BeginTransactor.class); //Guice injection
Transaction t = ... //get a transaction instance
t.apply(transactor);
Ce que je n'aime pas cette approche est (1) Non tous les types de transaction devrait être exécutable dans chaque phase du cycle de vie, mais chaque Transactor doit implémenter une méthode execute() pour chaque sous-classe de transaction et (2) Essentiellement, aucune des dépendances injectées n'est utilisée pour traiter plus d'un type de transaction. Essentiellement, mes implémentations de l'interface Transactor & ont beaucoup de crud non reliées ensemble. Idéalement, je voudrais juste avoir la méthode execute() sur l'objet de transaction lui-même, mais je ne veux pas que le code appelant sache le type de la transaction ou les dépendances dont elle a besoin. En outre, cela pourrait rendre les tests plus difficiles car je ne pourrais pas facilement simuler la méthode execute() s'il s'agissait d'une méthode concrète sur l'objet Transaction. L'utilisation de l'interface Transactor signifie que je peux facilement le simuler au besoin. Quelqu'un peut-il suggérer comment résoudre ce problème d'une manière sécurisée qui n'entraîne pas le regroupement de plusieurs comportements non apparentés dans le Transactor, mais qui conserve la testabilité et permet l'injection de dépendances?
C'est excellent, merci! J'avais soupçonné qu'il pourrait y avoir une approche AOP à ce problème, mais je ne savais pas exactement comment s'y prendre. –