A injeção de dependência é um padrão de design que facilita a codificação. Ele evita o incômodo de instanciar objetos com dependências complexas e facilita a criação de testes. Com a Biblioteca Couchbase.Extensions.DependencyInjection (GitHub)Se você não tiver um plano de negócios, poderá usar clusters e buckets do Couchbase na estrutura de injeção de dependência do ASP.NET Core.
Em minha última postagem no blog sobre Cache distribuído com ASP.NETNa postagem anterior, mencionei a biblioteca DependencyInjection. A injeção de dependência será explorada em detalhes nesta postagem. Fique à vontade para acompanhar os exemplos de código que criei, disponíveis em GitHub.
Configuração básica do Couchbase
Primeiro, você precisará de um cluster do Couchbase Server em execução. Você pode:
- Instale-o no local
- Executar em um contêiner com o Docker
- Use um serviço de nuvem como Azure
Em seguida, você precisará criar um balde no Couchbase. Esse pode ser o bucket "travel-sample" fornecido com o Couchbase ou um bucket criado por você mesmo.
Se você estiver usando o Couchbase Server 5.0, também precisará criar um usuário. Dê a esse usuário a permissão Cluster Admin e dê a ele o mesmo nome do bucket, apenas para manter as coisas simples, caso esteja acompanhando o processo.
Injeção de dependência com o Couchbase.Extensions
O Couchbase.Extensions (GitHub) tem como objetivo tornar mais simples o trabalho com o Couchbase Server e o ASP.NET Core. A injeção de dependência é apenas uma dessas extensões.
Você pode adicioná-lo ao seu projeto ASP.NET Core com o NuGet:
- Usando o Package Manager:
Instalar o pacote Couchbase.Extensions.DependencyInjection -Versão 1.0.2 - Com a interface do usuário do NuGet
- Use a linha de comando do .NET:
dotnet add package Couchbase.Extensions.DependencyInjection --versão 1.0.2
(A versão 1.0.2 é a versão mais recente no momento da redação deste documento).

Em seguida, você precisará fazer alterações em seu Inicialização classe em Startup.cs.
Na postagem do blog sobre cache, eu codifiquei a configuração:
|
1 2 3 4 5 |
services.AddCouchbase(client => { client.Servers = new List<Uri> { new Uri("https://localhost:8091")}; client.UseSsl = false; }); |
Isso é bom para demonstrações e publicações em blogs, mas você provavelmente desejará usar um arquivo de configuração para um projeto de produção.
|
1 |
services.AddCouchbase(Configuration.GetSection("Couchbase")); |
Supondo que você esteja usando o padrão Configurações do aplicativo.jsonatualize esse arquivo para adicionar uma seção do Couchbase:
|
1 2 3 4 5 6 |
"Couchbase" : { "Servers": [ "https://localhost:8091" ], "UseSsl": false } |
Ao criar uma seção "Couchbase", o módulo de injeção de dependência lerá diretamente do arquivo de texto appsettings.json.
Injeção de construtor
Depois que a injeção de dependência estiver configurada, você poderá começar a injetar objetos úteis em suas classes. Você pode injetá-los em controladores, serviços ou repositórios.
Aqui está um exemplo de injeção em HomeController:
|
1 2 3 4 5 6 7 8 9 10 11 |
public class HomeController : Controller { private readonly IBucket _bucket; public HomeController(IBucketProvider bucketProvider) { _bucket = bucketProvider.GetBucket("travel-sample", "password"); } // ... snip ... } |
Em seguida, vamos fazer um simples Obter em um documento conhecido em "travel-sample". Esse uso de token do SDK do Couchbase .NET mostrará a injeção de dependência em ação. Farei uma alteração no arquivo Sobre método de ação. Nesse método, ele recuperará um documento de rota e escreverá o número do equipamento.
|
1 2 3 4 5 6 7 8 9 10 |
public IActionResult About() { // get the route document for Columbus to Chicago (United) var route = _bucket.Get<dynamic>("route_56027").Value; // display the equipment number of the route ViewData["Message"] = "CMH to ORD - " + route.equipment; return View(); } |
E o resultado é:

Sucesso! A injeção de dependência funcionou e estamos prontos para usar um bucket do Couchbase.
Se não estiver usando "travel-sample", use uma chave do seu próprio bucket.
Baldes nomeados
Você pode usar a injeção de dependência para um único bucket em vez de ter que especificar o nome todas as vezes.
Comece criando uma interface que implemente INamedBucketProvider. Deixe-o vazio. Aqui está um exemplo:
|
1 2 3 4 |
public interface ITravelSampleBucketProvider : INamedBucketProvider { // nothing goes in here! } |
Em seguida, em Startup.cs, mapeie essa interface para um bucket usando AddCouchbaseBucket:
|
1 2 3 |
services .AddCouchbase(Configuration.GetSection("Couchbase")) .AddCouchbaseBucket<ITravelSampleBucketProvider>("travel-sample", "password"); |
Agora, o ITravelSampleBucketProvider é injetado em vez do provedor mais geral.
|
1 2 3 4 |
public HomeController(ITravelSampleBucketProvider travelBucketProvider) { _bucket = travelBucketProvider.GetBucket(); } |
Injeção de dependência mais complexa
Até este ponto, só usamos a injeção de dependência nos controladores. A injeção de dependência começa a render dividendos com gráficos de objetos mais complexos e profundos.
Como exemplo, imagine uma classe de serviço que usa um bucket do Couchbase, mas também usa um serviço de e-mail.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public class ComplexService : IComplexService { private readonly IBucket _bucket; private readonly IEmailService _email; public ComplexService(ITravelSampleBucketProvider bucketProvider, IEmailService emailService) { _bucket = bucketProvider.GetBucket(); _email = emailService; } public void ApproveApplication(string emailAddress) { _bucket.Upsert(emailAddress, new {emailAddress, approved = true}); _email.SendEmail(emailAddress, "Approved", "Your application has been approved!"); } } |
Em seguida, vamos usar esse serviço em um controlador (ou seja, torná-lo uma dependência). Mas observe que o controlador não está usando diretamente o bucket ou o serviço de e-mail.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public class ApproveController : Controller { private readonly IComplexService _svc; public ApproveController(IComplexService svc) { _svc = svc; } public IActionResult Index() { var fakeEmailAddress = Faker.Internet.Email(); _svc.ApproveApplication(fakeEmailAddress); ViewData["Message"] = "Approved '" + fakeEmailAddress + "'"; return View(); } } |
Se eu fosse instanciar ComplexService manualmente, eu teria que instanciar pelo menos dois outros objetos. Seria algo parecido com: novo ComplexService(novo BucketProvider(), novo MyEmailService(). É muita coisa que tenho que controlar e, se alguma dependência mudar, é preciso fazer muita manutenção manual.
Em vez disso, posso fazer com que o ASP.NET Core use a injeção de dependência para fazer tudo isso por mim. Voltar em Inicialização:
|
1 2 |
services.AddTransient<IEmailService, MyEmailService>(); services.AddTransient<IComplexService, ComplexService>(); |
Agora, o ASP.NET Core sabe como instanciar:
ITravelSampleBucketProvidergraças ao Couchbase.Extensions.DependencyInjectionIEmailService- Eu disse a ele para usarMyEmailServiceIComplexService- Eu disse a ele para usarComplexService
Por fim, quando AprovarControlador for instanciado, o ASP.NET Core saberá como fazer isso. Ele criará ComplexService ao instanciar MyEmailService e ComplexService. Ele injetará ComplexService automaticamente no construtor do `ApproveController`. O resultado final:

Para ver o exemplo completo, não deixe de conferir o código-fonte que acompanha esta postagem do blog no GitHub.
Limpeza
Não se esqueça de fazer a limpeza. Quando o aplicativo ASP.NET Core for interrompido, libere todos os recursos que o SDK do Couchbase .NET estiver usando. Na seção Configurar no Startup, adicione um parâmetro do tipo IApplicationLifetime:
|
1 |
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IApplicationLifetime applicationLifetime) |
Dentro disso Configurar configure um método ApplicationStopped evento:
|
1 2 3 4 |
applicationLifetime.ApplicationStopped.Register(() => { app.ApplicationServices.GetRequiredService<ICouchbaseLifetimeService>().Close(); }); |
Resumo
A injeção de dependência é um assunto rico. Livros inteiros foram escritos sobre ela e seus benefícios para seu aplicativo. Esta postagem do blog apenas arranhou a superfície e nem sequer abordou os benefícios da testabilidade.
O Couchbase.Extensions.DependencyInjection facilita a injeção do Couchbase no ASP.NET Core.
Se você tiver perguntas ou comentários, não deixe de conferir o Repositório do GitHub ou o Fóruns do SDK do Couchbase .NET.
E entre em contato comigo para fazer perguntas, deixando um comentário abaixo ou encontrando-me em Twitter @mgroves.
ao tentar definir
ervices.AddCouchbase(Configuration.GetSection("Couchbase"));
usando configurações, a chamada para : Configuration.GetSection("Couchbase"))
retorna nulo.
Portanto, esse não é o problema.
Parece que os dados foram transmitidos corretamente, mas quando tento chamar:
bucketProvider.GetBucket("statistics", "");
Recebo a mensagem "Bootsrap exception".
Arthur, você poderia publicar sua pergunta, juntamente com uma visão mais completa do seu código, no fórum do Couchbase .NET: https://www.couchbase.com/forums/c/net-sdk
Olá, Matthew, você poderia atualizar o código do repositório? Estou tendo problemas para usá-lo em um projeto ASP.Net Core 2.2.
Claro, Lahbabi, acabei de atualizar o repositório para o .NET Core 2.2. É provável que você não esteja realmente tendo problemas com o .NET Core 2.2. Meu palpite é que você esteja usando o Couchbase Server 5 ou mais recente, que alterou a forma como a autenticação funciona. (O único problema do .NET Core que vi é que eu tinha algumas coisas do loggerFactory que foram descontinuadas desde o .NET Core 1).
Obrigado, Matthew, está funcionando. Consegui me autenticar, mas não consegui encontrar onde clicar para buscar os dados... a amostra de viagem já está instalada no banco de dados.
Como vi seu maravilhoso exemplo de lista de presentes CRUD simples, esperava ver algo semelhante, mas desta vez usando a injeção de dependência. Como posso obter esse tipo de coisa com a injeção de dependência?
Você tem razão quando diz que esse exemplo não abrange todas as operações CRUD, mas o SDK não mudou muito desde que fiz o vídeo a que você se refere. Se você verificar o HomeController neste repositório, verá que ele ainda é apenas um objeto IBucket sendo usado. https://github.com/couchbaselabs/blog-source-code/blob/master/Groves/078AspNetCoreDependencyInjection/src/CouchbaseDIExample/CouchbaseDIExample/Controllers/HomeController.cs#L42
Você se interessaria por um vídeo que mostrasse o .net core 2.2, a injeção de dependência, o crud e o Couchbase juntos?
Eu não chegaria ao ponto de lhe perguntar isso :) Acho que colocar a Injeção de Dependência em ação com a API Rest na demonstração da lista de desejos, mesmo que apenas modificando o código existente, seria muito útil para mim e para muitos desenvolvedores do .Net Core que desejam tocar e gostar de lidar com o Couchbase. O exemplo de código da lista de desejos com a introdução do N1QL é um ponto de partida muito simples e muito conciso para levar o Couchbase a uma maior popularidade na comunidade de desenvolvedores do .Net Core.
Obrigado, esse é um bom feedback. Há algum tempo não atualizo meu conteúdo de "introdução ao ASP.NET", talvez seja a hora.
[…] https://www.couchbase.com/dependency-injection-aspnet-couchbase/ https://docs.couchbase.com/dotnet-sdk/current/hello-world/start-using-sdk.html […]
[…] https://www.couchbase.com/dependency-injection-aspnet-couchbase/ https://docs.couchbase.com/dotnet-sdk/current/hello-world/start-using-sdk.html […]