Esta deberia ser la parte uno y la otra la parte dos
Introducción
Principios SOLID en C# y .NET: Teoría y Práctica
Requisitos y Herramientas para Curso de Principios SOLID en C#
Prácticas de Código Limpio y Principios SOLID
Principios SOLID en Programación Orientada a Objetos
Principio de responsabilidad única
Principio de Responsabilidad Única en Programación Orientada a Objetos
Aplicación del Principio de Responsabilidad Única en C#
Principio de abierto/cerrado
Principio Abierto-Cerrado en C# para Extender Código sin Modificarlo
Aplicación del Principio de Abierto/Cerrado en Programación
Principio de sustitución de Liskov
Principio de Sustitución de Liskov en Programación SOLID
Aplicación del Principio de Sustitución de Liskov en Código SOLID
Principio de segregación de la interfaz
Principio de Segregación de Interfaces en Programación C#
Segregación de Interfaces en Programación SOLID
Principio de inversión de la dependencia
Principio de Inversión de Dependencia en Programación SOLID
Aplicación del Principio de Inversión de Dependencias en C#
Pruebas Unitarias y Principio de Inversión de Dependencias en .NET
Cierre
Principios Solid en C Sharp: Mejora y Aplicación Práctica
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
El principio de inversión de dependencias es fundamental para crear un código más flexible y mantenible. En este contexto, se analiza una API que utiliza un StudentController
en el que se evidencian dependencias directas con StudentRepository
y Logbook
. Estas dependencias directas violan el principio de inversión de dependencias porque implican una fuerte vinculación entre las clases, lo que dificulta la modificación o expansión del código.
La API examinada tiene una estructura base con métodos GET
y ADD
. Para ejecutar estos métodos, utiliza StudentRepository
y Logbook
. Aquí se observa que, al buscar o añadir estudiantes, se registra un evento en Logbook
, lo que implica que el StudentController
depende fuertemente de estas clases.
Las pruebas unitarias actuales verifican métodos como get
sin evitar las interacciones con el sistema, como la escritura de datos en un archivo mediante Logbook
. Esto puede resultar problemático ya que las pruebas unitarias no deberían realizar operaciones de entrada/salida. Idealmente, estas pruebas deberían enfocarse solo en la lógica, sin efectos colaterales o dependencias externas.
Para solventar el problema de la dependencia directa, se introducen interfaces para cada clase dependiente. Crear una interfaz abstracta para StudentRepository
y Logbook
desacopla el controlador de sus implementaciones concretas. Así, el StudentController
no depende directamente de un tipo específico de StudentRepository
o Logbook
, sino de un contrato común definido por las interfaces.
Crear la interfaz:
Defina la interfaz IStudentRepository
con los métodos requeridos:
public interface IStudentRepository {
IEnumerable<Student> GetAll();
void Add(Student student);
}
Implementar la interfaz: Aplique esta interfaz a la clase concreta:
public class StudentRepository : IStudentRepository {
public IEnumerable<Student> GetAll() {
// Implementación...
}
public void Add(Student student) {
// Implementación...
}
}
La misma lógica se aplica a Logbook
, creando una interfaz ILogbook
para encapsular su comportamiento.
La inyección de dependencias se realiza mediante constructor en el StudentController
. Donde antes se generaban objetos concretos con new
, ahora se espera recibir las interfaces en el constructor. Esto logra que el StudentController
actúe independiente de las implementaciones específicas.
public class StudentController {
private readonly IStudentRepository _studentRepository;
private readonly ILogbook _logbook;
public StudentController(IStudentRepository studentRepo, ILogbook log) {
_studentRepository = studentRepo;
_logbook = log;
}
// Métodos del controlador...
}
Para optimizar la arquitectura y facilitar la configuración global de las dependencias se utiliza el contenedor de dependencias de .NET, donde se registran las interfaces y sus implementaciones concretas.
services.AddScoped<IStudentRepository, StudentRepository>();
services.AddScoped<ILogbook, Logbook>();
Esta configuración asegura que los servicios estén disponibles globalmente para cualquier clase que lo requiera.
Gracias a la abstracción proporcionada por las interfaces, es posible introducir stubs o mocks para las pruebas unitarias, eliminando cualquier efecto colateral no deseado, como la creación de archivos o acceso a bases de datos.
Esto incrementa la robustez de las pruebas, permitiendo que se ejecuten en cualquier ambiente sin dependencias de sistemas externos o interacciones complejas. La inyección de dependencias hace que el StudentController
pueda ser probado con cualquier implementación que siga los contratos de las interfaces.
Implementar el principio de inversión de dependencias mediante interfaces y patrones de inyección no solo potencializa la flexibilidad del código sino también su capacidad de ser probado de manera uniforme y controlada. La meta es lograr un código que se adapta al cambio fácilmente, aislando y reutilizando componentes a través de contratos bien definidos.
Aportes 13
Preguntas 6
Esta deberia ser la parte uno y la otra la parte dos
Para las versiones de .NET Core y .NET para agregar los servicios, se usa el incluido nativamente por Microsoft, pero tambien hay otros nugets como Autofact: https://autofac.org/
Este video es: Aplicando el principio de inversión de la dependencia - Parte I
La mejor explicación que he visto de inyección de dependencias.
usualmente me ha tocado trabajar con inyección de dependencias en algunos proyectos y en la mayoria cuando vamos declaramos los tipos interfaces las declaramos como privadas y el nombre en este caso logbook por ejemplo lo manejamos comos _logbook.
Quedando en el constructor como
_logbook = log … en un caso como el que yo he visto quedaría _logbook = logbook.
Esto es solo un comment
la parte uno esta mal, esta en el lugar 15, debe estar en la 14
Ya está en el orden correcto, gracias !!!
El orden de las partes está mal, esta es el 14 y la anterior la 15
Hola Karol, aún está en el orden incorrecto. En el orden numérico del curso:
El 14 es la segunda parte.
El 15 es la primera parte.
sigue el problema
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?