Mensageria usando MSMQ

Olá tudo bem,

Hoje 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

 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

    [SerializableAttribute]
    public class Usuario
    {
        public string Nome { get; set; }
        public string Email { get; set; }
    }

Vamos a implementação da nossa classe Email Fila

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 

  [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.

Para que o Deus de nosso Senhor Jesus Cristo, o Pai da glória, vos dê em seu conhecimento o espírito de sabedoria e de revelação;Efésios 1:17

 

 

LEAVE A COMMENT