List and map injections
gengis Nov 22, 2010 5:27 PMDear all,
I am trying to see how weld/jsr299 can represent a real alternative to Spring in terms of dependency injection. While simple injections are easy with @Inject, I did not understand how to inject dependencies in these situations :
1) list injection. Example :
@Stateless public void MyDao { private List<DataSource> ds; public void someMethod() { // iterate on ds and use the first working DataSource; } }
question : how would you say to Weld I want to use this datasource and this datasource in this specific order
(assuming datasources are registered on the app server but here I do not want all of them).
2) Map injection. Example 1 :
@Stateless public void PublicationService { private Map<String, SpellChecker> checkers; // assuming SpellChecker is an interface with 2 implementations : FrenchSpellChecker and EnglishSpellChecker. Both would be session beans. public void publishDocument(Document doc) // document is a simple entity bean. { SpellChecker checker = this.checkers.get(doc.getLanguage()); // o.getLanguage() is a string, it could be fr or en. if(checker!=null) { checker.check(doc); } // do something with document, etc... } }
Example 2 :
@Stateless public void TranslationService { private Map<String, Interpreter> interpreters; // assuming Interpreter is an interface with 2 implementations : FrenchToEnglishInterpreter and EnglishToSpanishInterpreter. Both would be session beans. public String translate(String sentence, String langIn, String langOut) { Interpreter interpreter = this.interpreters.get(langInt+"-"+langOut); if(interpreter==null) { throw new UnsupportedTranslationException("Translation from "+langIn+" to "+langOut+" is not possible"); } return interpreter.translate(sentence); } }
Example 3 :
public interface Observer { void notify(Object o); } public void MessageProcessor { private Map<String, List<Observer>> observers; public Object process(Object message) { for(Observer observer : this.observers.get(message.getClass().getName())) { observer.notify(message); // each implementation of Observer is a session bean } return message; } }
Question for these simple but real-world examples : how would you inject the map ?
I am not trying to promote Spring but with xml configuration it's trivial to give to the container the 'recipe' to build these objects because xml allows to do exactly what you want, allows you to go beyond type matching injections. You can also register the same object in the container many times but with different injections, which is basically the definition of strategy pattern. Zero xml is appealing but reduces the injections to what can be 'autowired'.
I think (I hope) I missed something, thanks for your help;