La inyección de dependencias es un patrón de diseño que facilita la programación. Le ahorra la molestia de instanciar objetos con dependencias complejas y le facilita la escritura de pruebas. Con la Biblioteca Couchbase.Extensions.DependencyInjection (GitHub)Con ASP.NET Core, puede utilizar clústeres y buckets de Couchbase en el marco de inyección de dependencias de ASP.NET Core.
En mi última entrada sobre caché distribuida con ASP.NETmencioné la librería DependencyInjection. La inyección de dependencia será explorada en profundidad en este post. Siéntete libre de seguir los ejemplos de código que he creado, disponibles en GitHub.
Configuración básica de Couchbase
En primer lugar, necesitarás un clúster de Couchbase Server en funcionamiento. Puedes hacerlo:
- Instalarlo en las instalaciones
- Ejecutar en un contenedor con Docker
- Utilice un servicio en la nube como Azure
A continuación, deberá crear un cubo en Couchbase. Puede ser el bucket "travel-sample" que viene con Couchbase, o un bucket que crees tú mismo.
Si estás usando Couchbase Server 5.0, también necesitarás crear un usuario. Dale a ese usuario permiso de Cluster Admin, y dale el mismo nombre que al bucket, solo para mantener las cosas simples si estás siguiendo el proceso.
Inyección de dependencia con Couchbase.Extensions
En Couchbase.Extensions (GitHub) tiene como objetivo simplificar el trabajo con Couchbase Server y ASP.NET Core. Dependency Injection es solo una de estas extensiones.
Puede añadirlo a su proyecto ASP.NET Core con NuGet:
- Mediante el Gestor de paquetes:
Install-Package Couchbase.Extensions.DependencyInjection -Versión 1.0.2
- Con la interfaz de usuario de NuGet
- Utilice la línea de comandos .NET:
dotnet add package Couchbase.Extensions.DependencyInjection --version 1.0.2
(La versión 1.0.2 es la más reciente en el momento de redactar este documento).
A continuación, tendrá que hacer cambios en su Puesta en marcha
clase en Inicio.cs
.
En la entrada del blog sobre el almacenamiento en caché, codifiqué la configuración:
1 2 3 4 5 |
servicios.AddCouchbase(cliente => { cliente.Servidores = nuevo Lista<Uri> { nuevo Uri("http://localhost:8091")}; cliente.UseSsl = falso; }); |
Esto está bien para demostraciones y entradas de blog, pero es probable que desee utilizar un archivo de configuración para un proyecto de producción.
1 |
servicios.AddCouchbase(Configuración.ObtenerSección("Couchbase")); |
Suponiendo que esté utilizando la opción por defecto appsettings.json
actualice ese archivo para añadir una sección Couchbase:
1 2 3 4 5 6 |
"Couchbase" : { "Servidores": [ "http://localhost:8091" ], "UseSsl": falso } |
Haciendo una sección "Couchbase", el módulo de inyección de dependencias leerá directamente del fichero de texto appsettings.json.
Inyección de constructores
Una vez configurada la inyección de dependencias, puedes empezar a inyectar objetos útiles en tus clases. Podrías inyectarlos en Controladores, servicios o repositorios.
He aquí un ejemplo de inyección en InicioControlador
:
1 2 3 4 5 6 7 8 9 10 11 |
público clase InicioControlador : Controlador { privado sólo lectura IBucket _bucket; público InicioControlador(IBucketProvider bucketProvider) { _bucket = bucketProvider.GetBucket("viaje-muestra", "contraseña"); } // ... snip ... } |
A continuación, hagamos un simple Visite
sobre un documento conocido en "travel-sample". Este uso simbólico del SDK .NET de Couchbase mostrará la inyección de dependencias en acción. Haré un cambio en el Acerca de
método de acción. En ese método, recuperará un documento de ruta y escribirá el número de equipo.
1 2 3 4 5 6 7 8 9 10 |
público IActionResult Acerca de() { // obtener el documento de ruta de Columbus a Chicago (United) var ruta = _bucket.Visite<dinámico>("ruta_56027").Valor; // mostrar el número de equipo de la ruta VerDatos["Mensaje"] = "CMH a ORD - " + ruta.equipo; devolver Ver(); } |
Y el resultado es:
Éxito. La inyección de dependencia ha funcionado, y estamos listos para usar un bucket de Couchbase.
Si no utiliza "muestra-viaje", utilice una clave de su propio cubo.
Cubos con nombre
Puede utilizar la inyección de dependencias para un único cubo en lugar de tener que especificar el nombre cada vez.
Empiece por crear una interfaz que implemente INamedBucketProvider
. Déjelo vacío. He aquí un ejemplo:
1 2 3 4 |
público interfaz ITravelSampleBucketProvider : INamedBucketProvider { // ¡Aquí no entra nada! } |
A continuación, en Startup.cs, asigna esta interfaz a un cubo utilizando AddCouchbaseBucket
:
1 2 3 |
servicios .AddCouchbase(Configuración.ObtenerSección("Couchbase")) .AddCouchbaseBucket<ITravelSampleBucketProvider>("viaje-muestra", "contraseña"); |
Ahora, el ITravelSampleBucketProvider
en lugar del proveedor general.
1 2 3 4 |
público InicioControlador(ITravelSampleBucketProvider travelBucketProvider) { _bucket = travelBucketProvider.GetBucket(); } |
Inyección de dependencias más compleja
Hasta este punto, sólo hemos utilizado la inyección de dependencia en los controladores. La inyección de dependencia comienza a pagar dividendos con gráficos de objetos más complejos y profundos.
Como ejemplo, imagina una clase de servicio que utiliza un bucket de Couchbase, pero también utiliza un servicio de correo electrónico.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
público clase ServicioComplejo : IComplexService { privado sólo lectura IBucket _bucket; privado sólo lectura IEmailService Correo electrónico; público ServicioComplejo(ITravelSampleBucketProvider bucketProvider, IEmailService emailService) { _bucket = bucketProvider.GetBucket(); Correo electrónico = emailService; } público void AprobarSolicitud(cadena dirección de correo electrónico) { _bucket.Upsert(dirección de correo electrónico, nuevo {dirección de correo electrónico, aprobado = verdadero}); Correo electrónico.EnviarCorreo(dirección de correo electrónico, "Aprobado", "¡Su solicitud ha sido aprobada!"); } } |
A continuación, vamos a utilizar este servicio en un controlador (es decir, convirtiéndolo en una dependencia). Pero ten en cuenta que el controlador no utiliza directamente ni el cubo ni el servicio de correo electrónico.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
público clase AprobarControlador : Controlador { privado sólo lectura IComplexService _svc; público AprobarControlador(IComplexService svc) { _svc = svc; } público IActionResult Índice() { var fakeEmailAddress = Farsante.Internet.Correo electrónico(); _svc.AprobarSolicitud(fakeEmailAddress); VerDatos["Mensaje"] = "Aprobado" + fakeEmailAddress + "'"; devolver Ver(); } } |
Si tuviera que instanciar ServicioComplejo
manualmente, tendría que instanciar al menos otros dos objetos. Sería algo como: new ComplexService(new BucketProvider(), new MyEmailService()
. Son muchas cosas de las que tengo que hacer un seguimiento, y si cambia alguna dependencia, es mucho mantenimiento manual.
En su lugar, puedo hacer que ASP.NET Core utilice la inyección de dependencias para hacer todo esto por mí. De vuelta en Puesta en marcha
:
1 2 |
servicios.AñadirTransitorio<IEmailService, MyEmailService>(); servicios.AñadirTransitorio<IComplexService, ServicioComplejo>(); |
Ahora, ASP.NET Core sabe cómo instanciar:
ITravelSampleBucketProvider
gracias a Couchbase.Extensions.DependencyInjectionIEmailService
- Le dije que usaraMyEmailService
IComplexService
- Le dije que usaraServicioComplejo
Por último, cuando AprobarControlador
ASP.NET Core sabrá cómo hacerlo. Creará ServicioComplejo
instanciando MyEmailService
y ServicioComplejo
. Inyectará ServicioComplejo
automáticamente en el constructor de `ApproveController. El resultado final:
Para ver el ejemplo completo, consulte la página código fuente que acompaña a esta entrada de blog en GitHub.
Limpieza
No olvides limpiar después. Cuando la aplicación ASP.NET Core se detenga, libera cualquier recurso que el SDK .NET de Couchbase esté utilizando. En el Configure
en Startup, añada un parámetro de tipo IApplicationLifetime
:
1 |
público void Configure(IApplicationBuilder aplicación, IHostingEnvironment env, ILoggerFactory loggerFactory, IApplicationLifetime applicationLifetime) |
Dentro de ese Configure
configure un método AplicaciónParada
evento:
1 2 3 4 |
applicationLifetime.AplicaciónParada.Regístrese en(() => { aplicación.Servicios de aplicación.GetRequiredService<ICouchbaseLifetimeService>().Cerrar(); }); |
Resumen
La inyección de dependencia es un tema muy rico. Se han escrito libros enteros sobre ella y sus beneficios para tu aplicación. Esta entrada de blog apenas araña la superficie y ni siquiera cubre los beneficios de la testabilidad.
Couchbase.Extensions.DependencyInjection facilita la inyección de Couchbase en ASP.NET Core.
Si tiene preguntas o comentarios, no deje de consultar el Repositorio GitHub o el Foros del SDK .NET de Couchbase.
Si tiene alguna pregunta, déjeme un comentario a continuación o póngase en contacto conmigo en Twitter @mgroves.
al intentar fijar
ervices.AddCouchbase(Configuration.GetSection("Couchbase"));
utilizando la configuración la llamada a : Configuration.GetSection("Couchbase"))
devuelve null.
Así que este no es el problema ..
parece que los datos pasados corecttly pero cuando trato de llamar:
bucketProvider.GetBucket("statistics", "");
obtengo "Bootsrap exception"
Arthur, ¿te importaría publicar tu pregunta junto con una vista más completa de tu código en el foro de Couchbase .NET? https://www.couchbase.com/forums/c/net-sdk
Hola Matthew, ¿podrías actualizar el código del repositorio? Estoy teniendo problemas para utilizarlo en un proyecto ASP.Net Core 2.2.
Claro, Lahbabi, acabo de actualizar el repositorio a .NET Core 2.2. Es probable que en realidad no tuvieras problemas con .NET Core 2.2. Mi suposición es que estás usando Couchbase Server 5 o más reciente, que cambió la forma en que funciona la autenticación. (El único problema con .NET Core que vi es que tenía algunas cosas de loggerFactory que están obsoletas desde .NET Core 1).
Gracias Matthew, funciona, pude autenticarme pero no pude encontrar dónde hacer clic para obtener los datos... la muestra de viaje ya está instalada en la base de datos.
Desde que he visto tu maravilloso y sencillo ejemplo de lista CRUD Gifts, esperaba ver algo similar pero esta vez usando Inyección de Dependencia. ¿Cómo puedo obtener semejante cosa con Inyección de Dependencia?
Tienes razón en que este ejemplo no cubre todas las operaciones CRUD, pero el SDK no ha cambiado mucho desde que hice el vídeo al que te refieres. Si echas un vistazo a HomeController en este repositorio, verás que sigue siendo sólo un objeto IBucket el que se utiliza. https://github.com/couchbaselabs/blog-source-code/blob/master/Groves/078AspNetCoreDependencyInjection/src/CouchbaseDIExample/CouchbaseDIExample/Controllers/HomeController.cs#L42
¿Estaría interesado en un video mostrando .net core 2.2, inyección de dependencia, crud, con Couchbase todo junto?
Yo no llegaría al punto de pedirte eso :) Supongo que poner la Inyección de Dependencias en acción con la API Rest en la demo de wishlist, incluso sólo modificando el código existente, sería muy útil para mí, y para muchos desarrolladores .Net Core que quieren tocar y apreciar el trato con Couchbase, La muestra de código de Wishlist con la introducción de N1QL es un punto de partida muy simple y muy conciso para empujar a Couchbase a una mayor popularidad en la comunidad de desarrolladores .Net Core, la muestra actual es un poco complicada con su ComplexService y EmailService, etc .. para aquellos que sólo quieren empezar.
Gracias, es un buen comentario. Hace tiempo que no actualizo mi contenido sobre ASP.NET para principiantes, quizá sea el momento.
[…] 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 […]