Inyección de Dependencias en Go: para principiantes

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: ¿Por qué es importante la Inyección de Dependencias en Go?

\n\n

Go (Golang) es un lenguaje conocido por su simplicidad y rendimiento. Sin embargo, cuando tu proyecto comienza a crecer, el código puede convertirse rápidamente en un "espagueti", donde funciones y estructuras están rígidamente acopladas entre sí. Aquí es donde entra en juego la Inyección de Dependencias (DI).

\n\n

Para los desarrolladores principiantes, DI puede parecer un concepto complejo del mundo de Java o C#. Pero en Go, este patrón se implementa de manera elegante y sin frameworks. En este artículo, analizaremos qué es la Inyección de Dependencias, para qué sirve y cómo aplicarla correctamente en Go con ejemplos prácticos.

\n\n

Si quieres escribir código testeable, flexible y mantenible en Golang, este artículo es para ti.

\n\n

¿Qué es la Inyección de Dependencias (DI)?

\n\n

Inyección de Dependencias es un patrón de diseño en el cual un objeto recibe sus dependencias (otros objetos que necesita para funcionar) desde el exterior, en lugar de crearlos él mismo internamente.

\n\n

En palabras simples: en lugar de escribir myService := MyService{} dentro de tu código, "inyectas" una instancia ya preparada de myService en el constructor o método.

\n\n

Problema sin DI

\n\n

Imagina que tienes una aplicación para enviar notificaciones. Sin DI, el código podría verse así:

\n\n
package main\n\nimport "fmt"\n\ntype EmailNotifier struct{}\n\nfunc (e EmailNotifier) Send(message string) {\n    fmt.Println("Enviando email:", message)\n}\n\ntype UserService struct {\n    notifier EmailNotifier // Acoplamiento rígido\n}\n\nfunc NewUserService() *UserService {\n    return &UserService{\n        notifier: EmailNotifier{}, // Creamos la dependencia internamente\n    }\n}\n\nfunc (u *UserService) NotifyUser(message string) {\n    u.notifier.Send(message)\n}\n\nfunc main() {\n    service := NewUserService()\n    service.NotifyUser("¡Hola!")\n}\n
\n\n

¿Qué tiene de malo?

\n
    \n
  • Acoplamiento rígido: UserService está atado a EmailNotifier. Si quieres cambiar Email por SMS, tendrás que modificar el código de UserService.
  • \n
  • Dificultad para probar: No podrás probar UserService sin enviar un email real. Para pruebas unitarias, esto es crítico.
  • \n
\n\n

Solución con DI

\n\n

Ahora reescribamos el mismo ejemplo usando Inyección de Dependencias:

\n\n
package main\n\nimport "fmt"\n\n// Notifier — interfaz que abstrae el envío de notificaciones\ntype Notifier interface {\n    Send(message string)\n}\n\ntype EmailNotifier struct{}\n\nfunc (e EmailNotifier) Send(message string) {\n    fmt.Println("Enviando email:", message)\n}\n\ntype SMSNotifier struct{}\n\nfunc (s SMSNotifier) Send(message string) {\n    fmt.Println("Enviando SMS:", message)\n}\n\ntype UserService struct {\n    notifier Notifier // Dependencia a través de una interfaz\n}\n\n// NewUserService recibe Notifier desde el exterior\nfunc NewUserService(n Notifier) *UserService {\n    return &UserService{notifier: n}\n}\n\nfunc (u *UserService) NotifyUser(message string) {\n    u.notifier.Send(message)\n}\n\nfunc main() {\n    // Inyectamos EmailNotifier\n    emailService := NewUserService(EmailNotifier{})\n    emailService.NotifyUser("¡Hola por email!")\n\n    // Inyectamos SMSNotifier — ¡sin cambiar UserService!\n    smsService := NewUserService(SMSNotifier{})\n    smsService.NotifyUser("¡Hola por SMS!")\n}\n
\n\n

Ahora UserService no sabe qué notificador se está usando. Simplemente llama al método Send del objeto recibido. Esto es Inyección de Dependencias.

\n\n

Principales ventajas de DI en Go

\n\n

1. Testeabilidad (Objetos Mock)

\n\n

DI hace que tu código sea ideal para pruebas unitarias. Puedes reemplazar fácilmente una dependencia real por un "simulacro" (mock).

\n\n
package main\n\nimport "testing"\n\ntype MockNotifier struc                

Blogs

Book Recommendations