quarta-feira, 27 de fevereiro de 2008

Component do VRaptor só pode ter um construtor público

Nem tudo são flores com o framework MVC VRaptor. Uma classe anotada com Component só pode ter um construtor público. Senão o seguinte erro é exibido na inicialização do container web:
org.vraptor.config.ConfigException: cannot load classes
...
Caused by: org.vraptor.component.InvalidComponentException:
com.globo.ekzameno.vraptor.QuestionarioLogic component has 2 accessible constructors.
This is not desirable as it may reflect optional arguments and create complex attributes.
Ok, ok, isso não é o fim do mundo para o VRaptor, mas me atrapalhou um pouco com os testes unitários, pois eu pretendia fazer injeção de dependência por construtor. Como esse framework não me permite isso, terei que fazer por método set. Ou seja, ao invés de fazer assim:
public TiagoLogic() {
this(new RepositorioImpl());
}
public TiagoLogic(Repositorio repositorio) {
this.repositorio = repositorio;
}
Terei que fazer assim:
public TiagoLogic() {
setRepositorio(new RepositorioImpl());
}
public void setRepositorio(Repositorio repositorio) {
this.repositorio = repositorio;
}
Não é um grande problema, só questão de preferência mesmo. Prefiro por construtor.

4 comentários:

  1. Eu lembro do Guilherme Silveira ter falado alguma coisa sobre isso.
    Cheguei até mesmo a conversar com ele sobre este tipo de injeção de dependência via setter e via construtor.
    Uma outra forma que, não sei se o vraptor faz é a injeção através de atributo protected.

    ResponderExcluir
  2. Na verdade a injeção de dependencia que estou fazendo não é por framework. É na mão mesmo, não acho necessário utilizar um para isso. Então, no caso, utilizar por atributo protected seria pior ainda, pois necessitaria criar uma subclasse do meu componente. Argh!

    ResponderExcluir
  3. Oi Tiago!

    Esse é o principio do Good Citizen de IoC, diversos frameworks tem isso: voce so deve ter um construtor, para deixar as coisas mais Convention over Configuration.

    Mas nao entendi porque voce diz que nao tem injecao via construtor. Justo o contrario, ele obriga voce ter um construtor so para fazer essa injecao!

    Paulo

    ResponderExcluir
  4. Paulo, a injeção de dependencia a que me refiro é manual, sem usar nenhum framework nem mesmo o que vem com o VRaptor, pois como é algo pequeno não pretendo incluir muita complexidade. Ou seja, no teste ao instanciar a classe eu queria fazer pelo construtor enviando os objetos necessários por parâmetro.

    ResponderExcluir