DDD - Como vocês injetam seus repositórios nas entidades de negocio?

É mesmo estranho uma entidade se salvar. Por exemplo, a entidade está se salvando onde? O próprio comando save lembra que o estado da entidade está sendo levado (salvo) em algum lugar fora de onde sua aplicação está rodando naquele momento.

Já no caso do repositório, você tem os métodos add e remove. Você coloca o objeto no repositório. Vc recupera um objeto do repositório. Aonde seu objeto está sendo guardado? No repositório… o seu domínio + repositório é auto suficiente.

Repositório por si só já traz pra você este desacoplamento do mundo exterior (persistência), enquanto o AR parece trazer este mundo externo para dentro do seu domínio.

…voce prefere que ela seja estuprada por um Repositorio. Sem problemas. Eu prefiro objetos que não arrancam as cuecas dos outros nos meus sistemas, muitobrigado.

E tambem eh uma dependencia circular enorme.

[quote=Thiago Senna]Ou seja, assim como no spring, seu eu fizer

o guice conseguirá fazer a injeção de dependência nesta nova instância de aluno?
[/quote]

Não. Não é isso. Não ha milagres. Ninguem ( ainda) consegue interceptar new.
Vc faz assim

class AlgumServicoDeAlunos {

  @Inject  AlunoRepository rep; 

 public void fazAlgo (){
          
      Aluno aluno = rep.encontraPorInscrição(123454554);
      
      // faz algo

      rep.store(aluno);

    

 }

}

class AlunoRepository {

 @Inject DAO dao;
 @Inject Provider<Aluno> pa;

  public Aluno create(){
       return pa.get();
  }

  public ALuno encontraPorInscrição(int inscricao){
          Map <String,Object > res = dao.executeQuery("select * from aluno where aluno.inscricao = " + inscrisao);
           
          Aluno aluno = pa.get();

          // preenche aluno com os campos do mapa
          aluno.setID(res.get("id"));
          aluno.setInscricao(res.get("inscricao"));
          aluno.setNome(res.get("nome"));
         // claro que poderia usar algum mapper... é só um exemplo.
         // o ponto é que o aluno é obtido vazio e preenchido
           
         retorna aluno;
  }

}


class Aluno {

  @Inject  AlunoRepository rep; 


  public List<Notas> getNotas(Curso curso){
         return rep.getNotas(curso);
  }

}


// no modulo de configuração (que é uma classe)

binder.bind(Provider<Aluno>.class).to(AlunoFactory.class).in(Singleton.class) ;
binder.bind(AlunoRepository.class).to(AlunoRepositoryImpl1.class).in(Singleton.class) ;
binder.bind(DAO.class).to(JDBCDAO.class).in(Singleton.class) ;

Provider é uma interface do guice para atuar como fabrica. Vc pode criar suas proprias.
Repare que vc amarra classes/interfaces com classes, mas pode amarrar classes/interfaces com instancias tb.
E pode fazer a amarração num certo escopo (Singleton vem incluso, mas o padrão é “sem escopo” ao contrário do Spring em que o padrão é o singleton.

Nota: Embora o escopo se chame singleton ele é na realidade a implementação do padrão Shared Object.

humm, sobre o Guice, bacana, Sérgio.

mas…

O link que eu coloquei anteriormente é exatamente isso. Como interceptar o new. Eu já consegui implementar, só que usando o primeiro exemplo citado no exemplo, usando @Configurable.

Agora que o surgiram essas novas features no spring (aperfeiçoando as opções além de @Configurable), podemos optar por colocar uma anotação própria do domain para marcar o objeto para receber a dependência, ou se preferir, marcar seu objeto com uma interface de marcação.

[quote=MrDataFlex]
Mas e o ActiveRecord ? Faz isso muito bem, não acha ?[/quote]

IMHO, se alguém anota uma classe de @Entity e logo em seguida enfia um save() e passa a chamá-la de Active Record, esse cara não entendeu nem o que é um Contexto Persistente pra início de conversa.

Escreví isso na minha coluna da MundoJava no artigo de ORM. Entidades não possuem operação salvar().

[quote=Thiago Senna]humm, sobre o Guice, bacana, Sérgio.

mas…

O link que eu coloquei anteriormente é exatamente isso. Como interceptar o new.
[/quote]

?!? Pode citar onde diz isso ? Não encontrei.
O que o SPring faz é dar o new por vc (padrão factory) não interceptar o new.
Na realidade ele invoca o construtor via reflection. Nem sequer manipula o new per se.

[quote=rodrigoy][quote=MrDataFlex]
Mas e o ActiveRecord ? Faz isso muito bem, não acha ?[/quote]

IMHO, se alguém anota uma classe de @Entity e logo em seguida enfia um save() e passa a chamá-la de Active Record, esse cara não entendeu nem o que é um Contexto Persistente pra início de conversa.
[/quote]

@Entity marca o objeto como entidade não como persistente. Logo, pode ser usada mesmo fora de um contexto persistente. ( ha uma gambiarra no JPA associando entity==persistente. são duas coisas diferentes).
Se usa AR é porque não usa Contexto Persistente. Logo, não precisa entender o que é um Contexto Persistente porque nem está usando isso. AR é “contextless” e exactamente por isso é um problema.

Podem se usarem o padrão ActiveRecord …

Talvez ir direto no artigo seja meio confuso, mal.

Direto na fonte:

[quote]The support is intended to be used for objects created outside of the control of any container. Domain objects often fall into this category because they are often created programmatically using the new operator, or by an ORM tool as a result of a database query.

The @Configurable annotation marks a class as eligible for Spring-driven configuration. In the simplest case it can be used just as a marker annotation:[/quote]

http://static.springframework.org/spring/docs/2.5.x/reference/aop.html#aop-atconfigurable

Sergio… ou é Entidade ou é Active Record. Se vc colocou @Entity presume-se que você está usando JPA. Se está usando JPA presume-se que está usando um Contexto Persistente. Então, que sentido faria você anotar uma classe como @Entity sendo que ela não é persistente?

E mais uma vez… que sentido faz um Active Record ser anotado como @Entity.

Entity desde sempre nos dão sentido de continuidade. São objetos que você obtém hoje, altera e daqui a 2 meses eles vão manter esse estado. Que sentido faz uma entidade não ser persistente?

[quote=Thiago Senna]Talvez ir direto no artigo seja meio confuso, mal.

Direto na fonte:

http://static.springframework.org/spring/docs/2.5.x/reference/aop.html#aop-atconfigurable[/quote]

Isso só está dizendo que pode injetar coisas em objetos que não são criados no contexto. Não está dizendo
que intercepta o new.

Ele usa Load Time Weaving, e a injeção de dependência é feito por aspecto. No final, é só chamar um new da sua entidade e as dependências serão injetadas sem você tomar conhecimento disso. Ou seja, é DI + AOP.

Sergio… ou é Entidade ou é Active Record. Se vc colocou @Entity presume-se que você está usando JPA. Se está usando JPA presume-se que está usando um Contexto Persistente. Então, que sentido faria você anotar uma classe como @Entity sendo que ela não é persistente?

E mais uma vez… que sentido faz um Active Record ser anotado como @Entity.

Entity desde sempre nos dão sentido de continuidade. São objetos que você obtém hoje, altera e daqui a 2 meses eles vão manter esse estado. Que sentido faz uma entidade não ser persistente?
[/quote]

Ninguem falou que ela não é persistente. Apenas que não pertence a um Contexto de Persistencia. Ela é “detached” é livre e solta e se persiste a si mesma onde quiser. Annotações são metadados. Metadados não significam nada sem um contexto. Se o objeto não está no contexto do JPA a anotação entity é irrelevante.

Magia negra com AOP rulezowisky:
http://www.guj.com.br/posts/list/70275.java

Bom… a conversa encerra aqui. Sergio, realmente é difícil seguir uma linha de raciocínio com você. Na boa cara, sem briga. Se a porcaria do objeto tá marcado como @Entity você quer persistir ele num contexto JPA, não interessa se ele pode estar dettached. Precisa tomar cuidado, pois na maioria das vezes que ví um AR em JPA é porque o “arquiteto” não compreendeu direito os estados da entidade e não porque ele queria um AR.

Para os iniciantes: JPA não presume existência de Active Records (pelo menos nesse momento). Toda a infra é baseada em entities. Montar um AR goelabaixo só porque não compreendeu os estados da entidade é forçar a barra demais. Compreendo que é intuitivo colocar um salvar() naquilo que você quer salvar, mas não é assim que as coisas funcionam para uma entidade.

[quote=MrDataFlex]Usam instanciacao normal?
Usam algum container de DI ? Qual? Poderia ilustrar um exemplo de configuração dessa injeção?
Usam aspectos? Poderiam me passar um exemplo?

Estou com dúvidas nisso! Obrigado![/quote]

Eu passo o repositorio como parametro no metodo da entidade.

E só complementando a informação, já existe um movimentozinho nesse sentido: http://www.javapolis.com/confluence/display/JP07/A+First+Look+at+ActiveHibernate. Tudo bem que é pra JRuby, mas não impede a utilização com Java. Enfim, é uma abordagem interesssante. Resta saber se vai dar certo!

Um detalhe, quando voces citam AR marcado como @Entity vcs estão levando em consideração um atributo do tipo EntityManager ou não?

[quote=rodrigoy][quote=sergiotaborda a dois posts atrás]
@Entity marca o objeto como entidade não como persistente.
[/quote]

Bom… a conversa encerra aqui. Sergio, realmente é difícil seguir uma linha de raciocínio com você. Na boa cara, sem briga. Se a porcaria do objeto tá marcado como @Entity você quer persistir ele num contexto JPA,
[/quote]

Isso é o que vc acha. Por isso eu lhe disse que marcar como entity significa apenas isso: marcar como entity.
não significa ser persistente. Mas tb disse algo que vc olvidou: O JPA faz uma gambiarra associando entity==persistente. Tb lhe disse que @Entity é uma anotação , e como metadado que é não representa nada em si mesmo sem um contexto. Isso queria dizer que eu marco com @Entity o que bem me apetecer. Sem que isso tenha significado de persistencia. Apenas e quando, eu utilizar isso no contexto de JPA é que significa uma intensão de colocar o objeto/classe num contexto persistente. Mas isso acontece apenas e porque o JPA tem essa gamb. (O certo seria ter uma annotação @Persistable em separado de @Entity)

O objeto pode ser persistente sem utilizar JPA e mesmo assim usar @Entity. Ele pode ser marcado como entity e mesmo assim usar AR. (Claro que para começo de conversa ninguem falou de AR annotado com @entity … )

Não sei como naquelas duas frases vc encontra alguma contradição.