Cron Jobs — Hangfire com dotnet 6 -Prática

Douglas Modesto
Guide Lab
Published in
8 min readOct 19, 2022
hangfire-dotnet6

Vimos no artigo anterior os conceitos de um cron job, tais como suas terminologias e uma breve explicação do que é o Hangfire.

Se você ainda não viu esse artigo, clique aqui para ver.

Pois bem, nesse artigo vou apresentar a forma como eu costumo estruturar meu projeto e também como faço a configuração do Hangfire utilizando o .Net 6 pra isso, então, sem mais delongas, vamos nessa!

Criando o Projeto com .NET 6

  1. Inicie o Visual Studio e clique em Create a new Project.

2. Escolha o tipo de projeto: ASP.NET Core Web API.

ASP.NET Core Web API c#

3. Escolha um Nome para seu projeto, nosso exemplo irá se chamar: hangfire-dotnet-sample e então defina o local onde seu projeto irá ficar no seu computador. Agora clique em Next.

nome e local do projeto

Selecione .Net 6.0 (Long-term support) na opção framework. Habilite a opção do docker e então clique em Create.

seleção framework e habilitar docker

Uma vez feito os passos acima, deveremos ter algo semelhante a imagem abaixo.

solution da aplicação

Neste momento, iremos buscar as bibliotecas:

  • Hangfire
  • Hangfire.MemoryStorage
  • Hangfire.Dashboard.Basic.Authentication
Package Manager Console

Após a instalação, poderemos ver as bibliotecas nas dependências do projeto.

dependências do projeto

Agora iremos incluir a configuração do Hangfire na classe Program.cs
Essa configuração ocorre em dois pontos da classe, uma para Services e outra para App, conforme a imagem abaixo.

configuração Hangfire

Mude o launch do projeto para hangfire_dotnet_sample conforme imagem abaixo.

Uma última configuração no serviço, no arquivo launchSettings.json, modifique o valor da propriedade launchUrl para hangfire.

Após essa última configuração, ao executarmos a aplicação pressinando a tecla “F5” poderemos ver o endpoint “/hangfire” que configuramos na inicialização do projeto sendo apresentada no browser solicitando usuário e senha como também configuramos na classe programs.cs , conforme imagem abaixo.

solicitação de usuário e senha para acessar o hangfire

Após informar usuário e senha, deveremos poder ver o dashboard do hangfire sendo apresentado.

dashboard do hangfire

Opa sucesso, a configuração do Hangfire no nosso projeto ocorreu tudo conforme esperado.

Ai você deve estar se perguntando: “Ok, e agora eu faço o que com isso, como eu crio uma rotina pra rodar no hangfire?
Calma jovem Jedi, vamos fazer isso agora, segue comigo.

Antes de iniciarmos essa parte da implementação, gostaria de reforça um conceito muito importante que faz com que o Hangfire seja uma ferramenta poderosa e flexível.

Na Hangifire temos os seguintes itens: Jobs e Queues.
O Job é sua rotina de trabalho, e nessa rotina de Trabalho você pode ter diversas Queues que são as tarefas desse trabalho. Vamos fazer um breve exercício.

Pense que você precisa criar um Job para buscar informações de uma determinada fonte de dados e salvar essas mesmas informações em sua base de dados como se fosse uma base fria de informação, para que a sua aplicação frontend receba os dados dessa sua base fria.
Esse job que chamaremos de ProductsJob precisa buscar informações de listagem de produtos de Renda Fixa, Renda Variável e Fundos por exemplo. E cada uma dessas informações pode vir de fontes de dados diferentes.
Para você conseguir desacoplar melhor seu job, para cada tipo de produto podemos criar uma Queue especifica que irei chamar com os seguintes nomes Renda Fixa = FixedIncomeQueue, Renda Variável = EquityQueue e Fundos = FundQueue, e com isso separar a responsabilidade de cada uma delas em uma fila diferente. Perceba a importância do conceito de Jobs e Queues no Hangfire.

Uma vez esclarecido, bora pra implementação.

Para simular a integração com um serviço que retorne as informações de Produtos para o nosso job, vamos criar um serviço de integração que irá simular essa busca de dados para nós, essa integração irá se chamar InvestmentProductIntegration.

Primeiramente vamos criar uma pasta com o nome Integration e dentro dela vamos criar uma interface com o nome IInvestmentProductIntegration e criar uma classe com o nome InvestmentProductIntegration conforme a sequência de imagens abaixo.

camada de integração

Na interface IInvestmentProductIntegration vamos criar 3 métodos conforme imagem abaixo.

interface de integração com produtos de investimentos

Na classe InvestmentProductIntegration vamos implementar a interface acima conforme a imagem abaixo.

implementação da interface de integração de produtos de investimentos

Agora vamos fazer a injeção de dependência dessa classe e interface na nossa classe program.cs conforme imagem abaixo.

configuração de injeção de dependência

Agora vamos fazer a criação das nossas Queues que serão:

  • FixedIncomeQueue
  • EquityQueue
  • FundQueue

Para melhorar a visualização de nossas classes e interfaces, para as interfaces eu irei criar uma pasta chamada Domain e dentro da pasta domain iremos criar uma pasta chamada Interfaces e é dentro dessa pasta que iremos criar todas as nossas interfaces e vamos aproveitar pra remover para essa pasta a interface que criamos anteriormente para a camada de integração IInvestmentProductIntegration . Conforme imagem abaixo.

organização das interfaces

Perceba que a interface IInvestmentProductIntegration foi removida da pasta Integration e incluida na pasta Interfaces dentre da pasta Domain, blz.

Em cada uma das interfaces IFixedIncomeQueue, IEquityQueue e IFundQueue vamos incluir a interface IQueue conforme imagem abaixo.

Interface IFundQueue
Interface IFixedIncomeQueue
Interface IEquityQueue

Agora, vamos criar uma pasta chamada Queues na raiz da aplicação, e dentro dela vamos criar as seguintes classes:

  • FixedIncomeQueue.cs
  • EquityQueue.cs
  • FundQueue.cs

E para cada classe criada vamos incluir sua respectiva interface e fazer sua implementação conforme imagens abaixo.

classe FundQueue
classe FixedIncomeQueue
classe EquityQueue

Veja que os métodos criados estão lançando um exceção de NotImplementationException vamos resolver isso em alguns instantes.

Agora iremos fazer a configuração de injeção de dependência dessas classes e suas interfaces na classe program.cs conforme imagem abaixo

configuração da injeção de dependência

Agora vamos fazer a comunicação das Queues com o Serviço InvestmentProductIntegration de Integração que criamos, conforme imagem abaixo.

comunicação entre as FundQueue com a camada de Integração
comunicação entre as FixedIncomeQueue com a camada de Integração
comunicação entre as EquityQueue com a camada de Integração

Bom, ainda falta criar os Jobs, então vamos lá.

Dentro da pasta Interface lá na pasta Domain, vamos criar duas Interfaces que são:

  • IJob.cs
  • IProductJob.cs

A Interface IProductJob irá herdar da interface IJob conforme imagem abaixo.

Interfaces IJob e IProductJob

Agora vamos criar uma pasta chamada Jobs na raiz a aplicação e dentro dela vamos criar uma classe chamada ProductsJob e essa classe irá herdar da interface IProdutctJob que criamos no passo anterior.

criação da classe ProductJob

Agora vamos fazer a comunicação do Job com as Queues criadas anteriormente que ele irá executar.

implementação do Job ProductJob

Então da mesma, forma, vamos configurar a injeção de dependência da classe ProductsJob na classe program.cs.

configurração de injeção de dependência

Bom nesse momento, falta apenas um passo a ser feito para concluir a implmentação da nossa rotina de buscar produtos, porém precisamos tomar uma decisão.

Que tipo de Job estamos querendo criar?
E qual tipo de CronJob esse serviço se encaixa?

Vamos relembrar os tipos de jobs que temos.

tipos de jobs disponiveis no hangfire

Há diversos tipos de jobs disponibilizados no Hangfire, para esse nosso exemplo vamos considerar que essa é uma rotina que precisará se executada diariamente pelo menos uma vez.

Uma vez que decidimos vamos fazer essa configuração.

Na classe program.cs abaixo da configuração “FIM DA CONFIGURAÇÃO APP — HANGIFIRE” que fizemos no Inicio desse artigo.

configuração do Hangfire na parte do App

Vamos fazer a seguinte implementação.

Vamos utilizar o serviceProvider pra buscar uma instância do nosso job ProductsJob no container de injeção de dependência.

buscando instância do job ProductsJob

Agora iremos utilizar a classe RecurringJob que é disponibilizada pelo próproio Hangfire que instalamos na aplicação no incio do artigo e iremos fazer a seguinte configuração informando o Job que irá ser executado, a periodiciade de execução que é diariamente e o TimeZone que iremos informar o Universal.

configuração de um job recorrente

Depois de tudo, a configuração deverá ficar conforme a imagem abaixo.

configuração do Job Recorrente na classe program.cs

Agora após executarmos a aplicação podermos ver no dashboard do hangfire na aba de Tarefas recorrentes o nosso job.

Tela de Jobs Recorrentes

E quando o Job estiver rodando poderemos ver sua execução sendo feita na aba Tarefa.

execução do job na aba Tarefas.

E após todo esse percurso a solution da nossa aplicação deverá estar dessa forma.

solution da aplicação

Quanto código hein rs.

Bom pessoal era isso que eu tinha para mostrar pra vocês. Espero que tenha ficado claro como configurar o hangfire em um projeto .NET e também como eu faço pra organizar a estrutura de jobs e queues com o intuito de deixar simples a adição de uma nova queue ou mesmo um novo job.

Para acessar o respositório com todos este código é só clicar aqui.

Peço por gentileza para deixar uma estrela no repositório para que ele possa ganhar engajamento e com isso alcançar outros devs que possam se beneficiar desse conteúdo.

Me siga aqui no medium e no linkedIn para não perder nenhum artigo. Está vindo coisas boas por ai.

Agradeço por terem chegado até aqui comigo, até a próxima galera, um abraço =].

--

--

Douglas Modesto
Guide Lab

Pos Graduado em Inteligência Artificial e Arquitetura de Software distribuídos apaixonado por tecnologia, aprendendo a aprender ao mesmo tempo que ensina.