# Ist Dependency Injection im Validator möglich?



## mannohnenamen (12. Okt 2011)

Hallo Leute,

Ich programmiere mit JSF und möchte in einem Formular einen Wert mit Hilfe eines Validierers überprüfen. Die Überprüfung erfordert eine Datenbankanfrage, die mit einer Methode aus der Klasse QuestionService abgesetzt wird. 


```
public class QuestionTextValidator implements Validator {
    
    @Override
    public void validate(FacesContext context, UIComponent component, Object value)
            throws ValidatorException {
        
        @Inject
        QuestionService questionService;
  
         ...
}
```

Das Objekt wird leider nicht mit der entsprechenden Klasse instanziiert, bleibt daher null.
Gibt es eine Möglichkeit wie man es anders lösen kann oder ist es gänzlich ausgeschlossen?


----------



## maki (12. Okt 2011)

Meinst du mit "Dependency Injection" etwa CDI mit Weld/JBoss?

*verschoben*


----------



## mannohnenamen (12. Okt 2011)

Ich nutze JSF 2.0 und Glassfish 3.1.


----------



## maki (12. Okt 2011)

Dann geht das imho nicht, CDI ist da etwas eingeschränkt.


----------



## Sym (12. Okt 2011)

Es ist ja auch beabsichtigt, dass das nicht geht. Da ist CDI nicht eingeschränkt, sondern entspricht dem gewünschten Verhalten. 

Du müsstest den Lookup manuell durchführen.


----------



## maki (12. Okt 2011)

Hi Sym,

vielleicht stehe ich da auf dem Schlauch, aber warum sollte CDI keine DI in Validatoremn unterstützen sollen?

Ich meine, dass DI u.a. dafür da ist Lookups (und den Code & Fehlerbehandlung dafür etc. pp.) zu vermeiden.


----------



## Sym (12. Okt 2011)

maki hat gesagt.:


> Hi Sym,
> 
> vielleicht stehe ich da auf dem Schlauch, aber warum sollte CDI keine DI in Validatoremn unterstützen sollen?
> 
> Ich meine, dass DI u.a. dafür da ist Lookups (und den Code & Fehlerbehandlung dafür etc. pp.) zu vermeiden.


Bei Validatoren soll es das nicht, da es dort performance-technisch Probleme geben könnte. Bei Seam ist dies z.B. auch der Fall.

Validatoren sollen einfach, autark und performant gestaltet sein. Den letzten Punkt erreicht man vor allem bei der Abschaltung der Injection in den Beans.


----------



## maki (12. Okt 2011)

Hi Sym, bitte nicht falsch verstehen...

Hast du da eine Referenz für?
Fühle mich immer noch als ob ich auf dem Schlauch stehen würde, wieso sollte ein Lookup schneller sein als DI?

Meinst du dass die Validierung in Seam langsam ist oder wie?
Oder ist die CDI generell für Validatoren abgeschaltet aus Performancegründen?
Klingt irgendwie nicht so gut imho... so als ob man DI nicht wirklich verstanden hätte bei Weld... oder ich verstehe grade nix


----------



## Nogothrim (12. Okt 2011)

in reinem CDI geht das von Haus aus erstmal nicht, wenn man zusätzlich noch Seam Faces benutzt, dann natürlich schon (Kann auch sein, dass es da mittlerweile bei Apache eine Erweiterung für gibt). Meiner Meinung nach ist es auch völlig legitim das so zu machen, Validation ist halt oft nicht völlig kontextfrei, wenn man etwas fachliches prüfen möchte.


----------



## mannohnenamen (12. Okt 2011)

Das heisst für mich, dass ich die Prüfung über action machen muss, oder?


----------



## mannohnenamen (12. Okt 2011)

Ich habe es jetzt über action gelöst.

Danke für eure Anregungen.


----------



## Sym (12. Okt 2011)

maki hat gesagt.:


> Hi Sym, bitte nicht falsch verstehen...
> 
> Hast du da eine Referenz für?
> Fühle mich immer noch als ob ich auf dem Schlauch stehen würde, wieso sollte ein Lookup schneller sein als DI?
> ...


Sorry, ich habe mich wohl missverständlich ausgedrückt. 

CDI, sowie Seam unterstützen keine DI in Validatoren. Bei Seam ist die Begründung, den Perfomenzverlust, den DI mit sich bringt, reduzieren zu wollen. Der Validator kann als Bean schneller erzeugt werden, da die DI-Phase übergangen wird.

Meines Wissens sind viele Seam-Entwickler mit in CDI eingebunden, was das Verhalten an dieser Stelle erklärt.

Und natürlich ist ein manueller Lookup nicht schneller als DI und vor allem fehleranfälliger.


----------



## Sym (12. Okt 2011)

mannohnenamen hat gesagt.:


> Das heisst für mich, dass ich die Prüfung über action machen muss, oder?


Das ist nicht die beste Möglichkeit, weil Du damit nicht in der Validierungphase validierst. Und dort gehört es eigentlich hin. 

Wie gesagt, könntest Du den Lookup im Komponentenbaum selbst durchführen.

Lösen könntest Du das z.B. hiermit:

```
/**
	 * Loads bean from jsf context by creating a value expression for the given bean name.
	 * 
	 * @param <T>
	 *            The bean class type
	 * @param ctx
	 *            the faces context.
	 * @param clazz
	 *            the bean class type (could be Object.class)
	 * @param name
	 *            the name of the bean in the jsf context
	 * @return the jsf bean. Null if no bean exists in context.
	 */
	@SuppressWarnings("unchecked")
	private static <T> T get(final FacesContext ctx, final Class<T> clazz, final String name) {
		final ValueExpression ve = ctx.getApplication().getExpressionFactory()
				.createValueExpression(ctx.getELContext(), "#{" + name + "}", clazz);

		if (ve != null) {
			return (T) ve.getValue(ctx.getELContext());
		}

		return null;
	}
```


----------



## Nogothrim (12. Okt 2011)

natürlich unterstützt Seam DI in Validatoren / Converter etc. Das ist eines der Kern Features des Seam Faces Modul. Ganz wichtig auch: Seam 2 und Seam 3 sind völlig unterschiedliche Frameworks und sollten nicht verwechselt werden. Seam 2 ist ein kompletter Stack für JSF 1.2, Seam 3 ist nur noch eine mehr oder weniger lose Sammlung von CDI Extensions, genauso wie z.B. Apache CODI.

Beispiel aus der Seam Faces Doku:
Chapter 5. Faces Artifact Injection


----------



## Sym (13. Okt 2011)

Nogothrim hat gesagt.:


> natürlich unterstützt Seam DI in Validatoren / Converter etc. Das ist eines der Kern Features des Seam Faces Modul. Ganz wichtig auch: Seam 2 und Seam 3 sind völlig unterschiedliche Frameworks und sollten nicht verwechselt werden. Seam 2 ist ein kompletter Stack für JSF 1.2, Seam 3 ist nur noch eine mehr oder weniger lose Sammlung von CDI Extensions, genauso wie z.B. Apache CODI.
> 
> Beispiel aus der Seam Faces Doku:
> Chapter*5.*Faces Artifact Injection


Ich habe auch von Seam 2 gesprochen, denn daran wurde sich mit CDI orientiert.  Und da wurde das nicht unterstützt. Sorry, hätte ich deutlicher sagen soll.


----------



## mannohnenamen (14. Okt 2011)

@Sym
Danke für dein Vorschlag. Leider schaff ich es im Moment nicht auszuprobieren, aber es ist denk ich ein guter Ansatz.


----------

