Vamos falar sobre o poder da mensageria usando MSMQ, antes de iniciarmos o desenvolvimento caso você não conheça o MSMQ é indispensável acessar o link.

Nota: Quando criarmos a fila e necessário marcar a opção transacional

Agora Vamos imaginar que temos uma aplicação que recebe milhares de cadastro por dia, e a cada cadastro nossa aplicação deve enviar um e-mail desejando as boas-vindas para esse novo usuário.

O cadastro será feita de forma automática, quando o usuário enviar os dados eles serão persistido na base de dados, porém o envio do e-mail será feita de uma forma off-line, assim que o usuário realizar o cadastro a nossa aplicação enviara para o MSMQ.

E uma determinada rotina pegara a mensagem da fila e enviara o e-mail.

Definindo uma arquitetura básica de gerenciamento de Fila 

fila

Vamos a implementação da nossa classe Gerenciador de fila Base

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public abstract class GerenciadorFilaBase
{
       protected abstract string CaminhoFilaBase { get; }
       protected MessageQueueTransaction MessageQueueTransaction { get; set; }
       private MessageQueue MsmQBase()
       {
           var msmq = new MessageQueue(CaminhoFilaBase);
 
           if (MessageQueue.Exists(CaminhoFilaBase))
           {
               msmq.Formatter = new BinaryMessageFormatter();
               return msmq;
           }
 
           msmq = MessageQueue.Create(CaminhoFilaBase,true);
           return msmq;
       }
       protected void AdicionarProximoElemento(object objeto)
       {
           MsmQBase().Send(objeto, MessageQueueTransaction);
       }
       protected T RemoverProximoElemento<T>()
       {
           var proximoElemento = MsmQBase().Receive(MessageQueueTransaction).Body;
 
           return (T)proximoElemento;
 
       }
 
       public abstract void Processar();
}

 

Implementação da nossa classe Usuario

1
2
3
4
5
6
 [SerializableAttribute]
 public class Usuario
 {
    public string Nome { get; set; }
    public string Email { get; set; }
 }

Vamos a implementação da nossa classe Email Fila

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 
38
39
40
41
42
43
44
45
46
public class EmailFila : GerenciadorFilaBase
{
        protected override string CaminhoFilaBase
        {
            get { return @".\private$\email"; }
        }
 
        public void AdicionarEmailFila(Usuario usuario)
        {
            using (MessageQueueTransaction = new MessageQueueTransaction())
            {
                try
                {
 
                    MessageQueueTransaction.Begin();
                    AdicionarProximoElemento(usuario);
                    MessageQueueTransaction.Commit();
                }
                catch (Exception)
                {
 
                    MessageQueueTransaction.Abort();
                }
            }
 
        }
 
        public override void Processar()
        {
            using (MessageQueueTransaction = new MessageQueueTransaction())
            {
                try
                {
                    MessageQueueTransaction.Begin();
                    var proximoElemento = RemoverProximoElemento<Usuario>();
                    Console.WriteLine("Nome:{0}\nEmail:{1}", proximoElemento.Nome, proximoElemento.Email);
                    MessageQueueTransaction.Commit();
                }
                catch (Exception)
                {
 
                    MessageQueueTransaction.Abort();
                }
            }
        }
 }

 

Vamos examinar o código da classe acima, temos que implementar alguns atributos e métodos, uns deles é o CaminhoFilaBase nesse atributo precisamos informar o caminho da fila.

O método AdicionarEmailFila recebe por parâmetro um classe Usuario, com essa classe o método chama o AdicionarProximoElemento da classe base e adiciona o elemento na fila com o formato do corpo em binário, e para garantir a integridade estamos realizando a operação de forma transacional.

elemento-fila-binaria

 

O método Processar é responsável por remover o nosso objeto da fila e enviar o e-mail, nesse exemplo não implementamos o código responsável que envia o e-mail.

Implementação da classe E-mail fila Test responsável por realizar o teste 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[TestClass]
  public class EmailFilaTest
  {
      private readonly EmailFila _emailFila = new EmailFila();
 
      [TestMethod]
      public void Deve_adicionar_um_elemento_na_fila()
      {
          _emailFila.AdicionarEmailFila(new Usuario() { Nome = "Juliano Sales", Email = "juliano.salesg@gmail.com" });
      }
      [TestMethod]
      public void Deve_processar_o_proximo_elemento_da_fila()
      {
          _emailFila.Processar();
      }
  }

 

 

Conclusão: Com essa abordagem podemos diminuir drasticamente o processamento da nossa aplicação, sempre que tivermos um problema como o apresentado nesse post, podemos utilizar a mesma abordagem, até a próxima pessoal.

Exibições: 596

Comentar

Você precisa ser um membro de DevBrasil para adicionar comentários!

Entrar em DevBrasil

Comentário de Gabriel Haya em 16 julho 2014 às 14:38

valeu...

Comentário de Mauro Zamaro em 16 julho 2014 às 13:09

:) Bom artigo. 

Poderia avaliar também este: http://www.linhadecodigo.com.br/artigo/1386/msmq-tem-mensagem-pra-v...

[]s

© 2017   Criado por Ramon Durães.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço