Problemas com Worker Services e Injeção de dependência no .NET?
Existe um problema que pode ocorrer caso você utilize um Worker Service que faça uso de Entity Framework na hora de Injetar dependências !
Ao inicializar a sua aplicação a mensagem apresentada será esta:
Cannot consume scoped service ‘nome do DbContext’ from singleton ‘CurrencyExchangeWorker.Services.ICurrencyService’.)
Mas como pode ter acontecido isso, se meu serviço foi instanciado como “Singleton” ! Veja a inicialização:
Este problema ocorre devido ao ciclo de vida do Worker Service que é do tipo “Singleton”, porém ao utilizar o banco de dados, é gerada uma instância “Scoped”.
Só para relembrar:
Singleton
O serviço é criado uma única vez e a mesma instância é passada para todas as chamadas dele.
Scoped
Uma única instância é criada por requisição. Então se o serviço for chamado em vários lugares em uma única requisição, a mesma instância será passada.
Sendo assim, temos que fazer alguma modificação na nossa implementação padrão fornecida pelo template do Worker Service criada automaticamente.
O que fazer então ?
O problema está na forma como o Contexto do banco de dados é criado, pois o comando AddDbContext cria um contexto dentro do ciclo de vida “Scoped”, que é incompatível com o Worker Service é instanciado na forma padrão como “Singleton”.
Então vamos ajustar a nossa aplicação assim:
Primeiro, vamos ajustar o serviço dentro do ciclo de vida Scoped assim como o Contexto.
Depois, dentro da classe “Worker”, vamos mudar a sua inicialização, onde ao invés de recebermos a interface do serviço, receberemos uma interface “IServiceProvider” para que possamos obter as classes depois utilizando-a.
Além disso, vemos que o método “ExecuteAsync” está chamando um outro método “DoWorkAsync”.
É aqui que a mágica acontece, vamos utilizar o nosso “ServiceProvider” para criar um “ServiceScope” e assim com este objeto, obter uma instância “Scoped” da classe do serviço “ICurrencyService”, e desta forma, poder utilizar serviços “Scoped” dentro de um Worker que é “Singleton”.
E assim o problema foi resolvido !
Gostou do artigo? clique no ícone👏e me siga para ver as próximas publicações !!