Remplacer usine de création de l'objet avec le CDI mécanisme
J'ai voulu introduire CDI (Soudure) à notre projet, et maintenant un peu de mal avec les objets qui sont construits manuellement.
Donc nous avons quelques classes de mise en œuvre de la IReport
interface, qui ont un champ qui doit être injecté. C'est null lors de l'exécution, parce que toutes ces classes sont générées par le ReportFactory
dans une classe ReportController
.
private Map<String,Object> generateReport(ReportInfo ri, ...) {
//some input validation
IReport report = ReportControllerFactory.getReportInstance( ri.getClassName() );
//...
}
Je suis conscient que je peux utiliser le @Produces
annotation avec un autre annotations personnalisées dans le ReportControllerFactory
, mais comment puis-je utiliser le @Inject
pour une variable qui ne peut être créé, après la validation de certains a fait, à l'intérieur de une méthode? Et comment dois-je présenter le paramètre ri.getClassName()
? L'objet ri
n'est pas connue au moment de l' ReportController
est construit.
Merci beaucoup!
Salutations,
Sebastian
Modifier à Jul 08, 2011 (10:00):
ReportFactory classe:
public static IReport getReportInstance( String className ) throws ReportException {
IReport report = null;
try {
Class<?> clazz = Class.forName( className );
report = (IReport) clazz.newInstance();
}
catch ( Exception e ) { … }
return report;
}
Edit 2 (Sélection du rapport de mise en œuvre)
L'instance de rapport est sélectionné par certains chemins qui vont de la JSF frontal pour le ReportController. Le ManagedBean appelle un bean de session, qui a plusieurs méthodes, selon sur quel bouton a été pressé où. Toutes ces méthodes de définir le rapport nom et l'appeler le plus générique de la méthode sendOrGetReport
. Cette méthode permet de sélectionner la clé unique pour le rapport spécifié à partir de la base de données et décide de envoyer un e-mail ou livrer immédiatement le rapport. Imaginons qu'il doit être livré.
Puis le ReportController
entre en jeu. Il va chercher un ReportInfo
objet basé sur la clé unique et d'autres informations fournies par les méthodes ci-dessus et appelle la ReportFactory
pour créer un rapport de type ri.getClassName()
.
De fantaisie, hein? Je pense que l'ensemble de cette section pourraient avoir besoin d'un refactoring. Si vous ne voyez pas facile spot, j'ignore l' @Inject
dans le rapport de mise en œuvre et de faire un JDNI de recherche pour cette ressource.
Oui, le "rapport" a un champ qui a une annotation @Inject. Donc j'ai en quelque sorte de dire CDI à résoudre que par injection. J'ai édité ma question et ajouté le code d'usine.
Ok, mais dans ce cas, puisque vous êtes à l'aide de clazz.newInstance() pour créer le IReport bean, il ne peut pas se injectés de dépendance droit ? Je ne sais pas votre DI-cadre, mais vous avez probablement d'utiliser une sorte de "injecteur" / "beanRepository" / "beanFactory" dans le cadre afin de créer les haricots avec la dépendance de l'injection, n'est-ce pas ?
Pouvez-vous mettre à jour votre question avec un peu plus explicite des informations sur les critères dont vous avez besoin pour décider qui IReport de mise en œuvre vous avez besoin au moment de l'exécution?
Merci, je l'ai fait. Assez compliqué, mais ça pourrait aider.
OriginalL'auteur Sebastian Wramba | 2011-07-08
Vous devez vous connecter pour publier un commentaire.
L'idée derrière CDI (et d'autres DI-cadres) afin de gérer les dépendances est de prendre le contrôle de la gestion du cycle de vie des beans. Cela implique - entre autres choses - que vous ne pouvez pas interférer avec la création de la gestion des haricots si vous voulez qu'il soit géré par le conteneur.
Certainement, cela ne signifie pas que votre scénario est insoluble, vous avez juste à changer votre point de vue un peu 😉
L'idée est de travailler avec la gestion des haricots (évidemment), mais que votre propre logique de décider quelle instance de toutes les instances disponibles est la bonne.
Avec autant de grains de beantype IReport que vous le souhaitez
Et un automagical utilisation comme cette
Voir ici et ici pour plus d'informations.
Si je n'ai pas mal compris votre problème, cela devrait vous apporter de l'avant - n'hésitez pas à poster d'autres questions /commentaires.
Mise à JOUR:
Tout pourrait être simple si quelque chose comme ceci correspond à vos besoins:
Avec l'utilisation comme cette
OriginalL'auteur jan groth
Afin de créer dynamiquement le droit rapport de classe, un petit changement pour la accepté de répondre à résoudre le problème. La solution est le fait que l'Instance<...> vous donne la liste de tous les fèves, qui sont d'un certain type. Un produit d'annotation n'est pas nécessaire.
Faire une usine de classe qui permet de sélectionner entre le injecté cas au moment de l'exécution
Maintenant, la classe qui a besoin d'une façon dynamique de rapport sélectionné, peuvent utiliser cette usine.
Merci pour cette réponse! Il a BEAUCOUP aidé, surtout, cette indication de nice avec la
Instance<...>
de construire!Excellent. Ce sont avérées très utiles pour moi.
Mieux que Mieux.
OriginalL'auteur yoda
Ok, donc si je ne suis pas trop mal, basé sur la doc ( Est-ce le bon cadre ? http://docs.jboss.org/seam/3/latest/reference/en-US/html/solder-beanmanagerprovider.html ), votre usine aurait besoin pour obtenir un handle pour le BeanManager singleton (soit le faire de l'injection, ou d'appeler un accesseur du cadre) , et de faire quelque chose le long des lignes de
En supposant que votre CDI a été configuré pour s'occuper de l'éventuel nom de la classe, vous devriez obtenir le bon grain de café. Maintenant, cela peut toujours être la même instance ; je ne sais pas si c'est ce que vous avez besoin, désolé.
Désolé Si je me trompe ; en espérant que ça aide.
OriginalL'auteur phtrivier