Salve, Deus, beleza? Continuamos essa saga aqui no Domain Dream Design. Na última aula, nós conseguimos fazer toda a integração aqui da parte dos eventos de domínio com o Nest, também testando aqui um listener. Vimos que é o registro do listener, se faz ali no módulo em si que você está manipulando. Mas a gente vai querer que um listener mais especializado, com mais necessidades, seja registrado aqui, como isso funcionaria em relação com o Mesh. O meu listener vai querer acessar repositório e outras coisas que eu tenho na minha aplicação. Até mesmo outros serviços. Eu quero criar um listener aqui para poder enviar um e-mail. Beleza. Então, você vai ter que injetar um serviço de e-mail e enviar o e-mail após um partner ser criado. Enfim. Então, vamos ver isso aqui nessa aula. A primeira coisa que a gente deve ter senso em relação ao listener, ele, no nível de camadas, ele está no mesmo nível de um application service. Então, se eu for criar um listener aqui na minha parte de eventos, vamos porque eu quero criar um listener aqui, para poder fazer essa separação, vou colocar aqui o nome de handlers ou listeners, e vou criando as minhas classes aqui. Então, vamos colocar aqui my handler ponto handler ponto ts. Na verdade, é até bom a gente colocar um nome mais sugestivo. É bom que você coloque exatamente o que você vai fazer. Vou enviar um e-mail, então sendEmail, ou qualquer outro nome. Mas vou trabalhar aqui com esse MyHandler como exemplo, que a gente já vai entendendo como que funcionam as coisas. Unlisting, na verdade, é justamente para você poder tirar toda a responsabilidade de dentro do seu application service. Porque a gente poderia enviar um e-mail daqui, sim, poderia injetar um serviço de e-mail aqui no meu application service e fazer um envio de e-mail. Mas daqui a pouco eu perco controle sobre esse negócio que está acontecendo aqui. Fica mais difícil mantê-lo, porque ele tem muitas responsabilidades. Fica difícil de testar. Então, justamente um dos poderes que a gente tem com os eventos de domínio é criar classes que fiquem responsáveis por essas pequenas tarefas que a gente tem que fazer após o processo de negócio acontecer. Então, vamos colocar aqui o MyHandler. Handler, eu vou repetir justamente por conta do nome ali. Se a gente fosse criar um nome oficial, não teria esse MyHandler aqui antes. Então, ele vai implementar. A gente poderia talvez criar um implement para ele, eu acho que seria interessante. Então vamos aqui na parte do command, que a gente está criando tudo. Eu vou criar aqui, como ele fica sempre na camada de aplicação, vou criar essa domain event handler.interface. Eu vou exportar uma interface que é o idomainEventHandler então todo handler deve ter um handle que vai receber aqui um idomainEvent poderia colocar aqui também que ele poderia receber vários tá ou até um N se eu quisesse generalizar eu vou deixar assim e já coloco que ele vai lidar ali com promessa que já vira um padrão então a gente vai implementar o IDomainEventHandler e aqui eu recebo o evento. Então eu quero receber aqui o que? um partner created. Então eu já tenho aqui o tipo do meu evento e aqui eu posso fazer o meu processamento conforme eu queira. Ah, eu já tenho aqui o tipo do meu evento e aqui eu posso fazer o meu processamento conforme eu queira. Ah, eu posso acessar aqui, se eu quiser, um application service? Aí vem a primeira dúvida. Não, tá? Application service não deve ser acessado pelo seu render. Mas eu posso acessar um repositório? Sim, você pode acessar um repositório aqui. Eu posso acessar um serviço de pagamento? Sim, você pode acessar. Qualquer coisa que não seja um application service, a ideia é que o application service seja independente dos renders. Se você tem um processo de negócio dentro do render aqui, você vai pegar repositório e outros serviços para poder fazer o seu processo de negócio. Então, aqui, eu poderia justamente manipular agregados. E no momento que eu vou fazer uma manipulação de agregados, não vou enviar um e-mail, vou só manipular agregados, e depois eu vou acabar fazendo um partner repo add ou qualquer repo add, perceba que nós estamos sobre o domínio do Unit of Work. Então, o listener, os listeners acontecem nessa linha aqui. Então, qualquer coisa que a gente fizer, está sobre o controle transacional do Unit of Work. Então, isso é muito legal, porque a gente não precisa se preocupar em ficar salvando e ficar matando o que já foi feito ali. Não, já está tudo sobre o controle transacional. Então, só preciso continuar utilizando os repositórios da maneira que eu queira. Mas, quando você manipula agregados aqui, pode ser que esses agregados, eles disparem mais eventos. Até tem uma coisa que eu esqueci de fazer aqui, que é eu vou fazer a publicação depois a gente pode pegar o aggregate root e fazer um clear nele. É algo que eu esqueci, porque eu não tenho mais os eventos ali. Mas quando eu chego no render, se eu manipulei agregados, esse agregado pode ter registrado outros eventos. Aí nesse caso, seria interessante aqui, isso é uma dica muito importante, que a gente importe o domain event manager. Aqui. aqui eu não vou esperar mais para fazer essa publicação não vai ser delegado ao application service aqui eu já vou fazer esse disparo na hora a gente já publica aqui os agregados específicos eu passo aqui o meu agregado já faço a publicação obviamente com a wait publica aqui os agregados específicos. Eu passo aqui o meu agregado. Já faço a publicação, obviamente, com a wait. Então, aqui, sequencialmente, se o handler tem novos eventos de domínio, outros handlers vão ser ativados, até que todo mundo é processado, aí esse for aqui dá continuidade quando isso tudo acabou. Então, eu posso ter um processo bem complexo nesse sentido. Beleza. Vamos pegar aqui e fazer um console.log desse evento aqui que aconteceu. Mas a questão é como a gente vai lidar com ele aqui, porque eu tenho um handler que foi criado lá no core, que não é um serviço nativo do Nest, e para que o Nest consiga gerenciá-lo, a gente vai ter que registrar ele aqui também. Então, ele vai ter que virar um outro serviço. Mas aqui tem uma pegadinha que eu vou falar pra vocês sobre essa questão desse handler. Como que a gente pode fazer aqui? Esse aqui é do orderService, né? Termina-se aqui embaixo. Então, eu quero prover um myHandler. E a gente vai chamar aqui a nossa classe. O que eu tenho que injetar nela, que a gente colocou? O que precisa ser injetado? Eu preciso injetar primeiro o repositório e depois o event manager. Então aqui vem o partner repo e domain event manager. Aí aqui vai ser domainain Event Manager, tá certo? Agora Partner Repo Que é do tipo Partner Repository E Domain Event Manager Que é do tipo Domain Event Manager Tá Então a gente vai precisar aqui que é do tipo DomainEventManager. Então, a gente vai precisar aqui do IPartRepository e DomainEventManager. Está aqui o meu handler. Como um serviço qualquer, ele precisa lidar com a Factory para poder ser criado, porque ele não está... tem os decorators aí do próprio Nest. Aí aqui embaixo, aqui embaixo, o que a gente vai fazer aqui? Eu poderia passar um private com a referência desse listener aqui. Isso seria uma carga muito grande para o módulo, porque vai fazer com que logo de cara o módulo já tenha que carregar todas essas referências e etc. A gente pode adiar, porque eu não estou ouvindo nada agora, não preciso fazer nenhum processamento. Então, nós vamos utilizar aqui um serviço do Nest, que é o ModuleRef. ModuleRef. Esse cara aqui é capaz de pegar as instâncias do próprio módulo. Então, aqui dentro, por exemplo, eu quero ouvir esse partner create aqui. Eu chamo o meu, na verdade, o meu module ref, ponto resolve, passando qual é o serviço que eu quero carregar. Eu posso carregar qualquer um. Na verdade, o meu module ref.resolve. Passando. Qual é o serviço que eu quero carregar? Eu posso carregar qualquer um. E aqui eu vou ter o que como resultado? A instância desse listener. E eu chamo o handle e passando ali o evento. Aqui, na verdade, até para ficar um pouco melhor, eu vou colocar um async aqui. Dividir isso em duas linhas para ficar mais elegante. A gente pode colocar o nosso handler aqui. Isso aqui é uma promessa. É importante entender como que esse module ref está acessando o container de serviços do Nest, porque ele sempre vai gerar um novo handler. Eu estou colocando essa lógica aqui justamente para forçar que o handler que está sendo executado naquele momento seja um novo handler, para até evitar que a gente tenha dependências que devam ser geradas para cada requisição, que elas sejam compartilháveis. Então, o resolve vai forçar isso aqui para a gente. Então, aqui tem que ser um await. Eu posso colocar aqui que é o my handler. Ele está cheiando aqui porque eu não fiz o alinhamento então agora aqui fica await handler.handle pronto tá, vamos ver aqui se ele iniciou tudo bonitinho, show de bola agora lá no api.http se a listagem está correta e vamos fazer um novo post. Aqui, nosso console.log aconteceu com sucesso ali do evento, então a gente conseguiu capturar o evento aqui dentro, ou seja, a gente consegue fazer qualquer tipo de processo de negócio. Essa forma que está aqui dentro do nosso módulo já é uma maneira um pouco melhor da gente se organizar. Mas a gente pode até criar um padrão por exemplo, o que a gente poderia fazer aqui dentro do handler a gente poderia criar isso inclusive poderia até ficar aqui poderia ter um método, se bem que não daria para colocar esse método porque ele teria que ser estático. Não dá para poder fazer com essa interface, teria que pelo menos criar uma outra, mas a gente poderia criar assim, um listens to e aqui o meu objetivo é devolver, eu posso me inscrever em vários tipos de eventos. Então, eu passo aqui todos os eventos que eu quero me inscrever. Aí agora, lá aqui dentro, eu posso pegar... Como que a gente poderia fazer isso de uma forma mais adequada? Se eu pegar o evento em si e chamar o método estático dele, a gente pode fazer assim, myHandler listensTo for each, para cada event name que eu tiver, aí nós vamos fazer aqui o nosso registro. Então eu pego esse trecho aqui e jogo pra cá. Isso aqui vai ser sempre uma string e vem aqui no lugar, nesse lugar aqui. EventName. esse lugar aqui event name aqui eu coloquei errado e aqui não precisaria necessariamente passar o evento para lá, porque aí tornaria mais genérico essa nossa execução aqui, porque depois eu poderia até criar um outro lugar para poder registrar todos esses licences e deixar que nesse lugar já fizesse todo o código, já fizesse uma abstração para já poder ligar o renderer com o seu devido evento, mas fica bem melhor. Eu poderia até criar aqui uma RAID list antes de fazer um FOR. Enfim, dá para a gente poder melhorar isso aqui bastante. Vamos dar uma testada nisso aqui para ver se continua da mesma forma. Está aqui. Então ficou bem melhor ainda, porque aqui agora eu não sei mais o evento que tá sendo feito. Eu só sei que eu tô pegando o Listen To e estou jogando pra cá. Então agora a gente consegue criar listeners e os eventos pra poder nos inscrever em qualquer coisa que tá acontecendo ali no núcleo do nosso domínio. Então, pessoal, vamos seguir na nossa saga. É isso aí e até a próxima.