Resumen

Construir un sistema de inventario completo en C# requiere algo más que métodos sueltos: necesita una capa que coordine repositorio, almacenamiento y reportes sin exponer la complejidad interna. Eso es exactamente lo que se logra al aplicar el patrón facade a través de una clase llamada InventarioService, que se convierte en el punto de entrada único para toda la lógica de negocio.

¿Qué hace el patrón facade en InventarioService?

El patrón facade simplifica la interfaz de un sistema al ofrecer un único punto de acceso que coordina múltiples colaboradores internos [0:06]. En este caso, InventarioService trabaja con tres dependencias:

  • InMemoryProductRepository: almacena los productos en memoria.
  • JsonInventarioStorage: gestiona la persistencia en formato JSON.
  • Una ruta de archivo (inventario.json) donde se guardan los datos.

Dentro del constructor se instancian estos colaboradores y se define la ruta por defecto como inventario.json [0:49]. Inmediatamente después se implementa el método CargarInventario, que verifica con un condicional if si el archivo ya existe en la ruta indicada. Si existe, carga la lista de productos y los agrega al repositorio mediante un ciclo foreach [1:10].

¿Cómo se implementan los métodos CRUD?

Las operaciones CRUD (crear, leer, actualizar y eliminar) se traducen en cinco métodos concretos [1:30]:

  • AgregarProducto: recibe nombre, precio, cantidad y categoría, crea el producto con ProductFactory.Crear y lo añade al repositorio. Al final llama a _Persistir() para guardar los cambios.
  • ObtenerTodosLosProductos: retorna un IEnumerable<Producto> usando repository.ObtenerTodos().
  • ObtenerProductoPorId: recibe un int como parámetro y aplica el operador de nulabilidad (?) porque el resultado puede ser nulo [2:15].
  • ActualizarProducto: obtiene el producto por ID, verifica que no sea nulo y luego actualiza nombre, precio, cantidad y categoría.
  • EliminarProducto: recibe el ID y llama a repository.EliminarPorId().

¿Qué métodos de búsqueda y consultas se incluyen?

Se crean varios métodos de tipo IEnumerable<Producto> para búsquedas específicas [2:55]:

  • BuscarPorCategoría: filtra productos según la categoría recibida.
  • BuscarPorNombre: filtra por coincidencia de nombre.
  • ObtenerProductosBajoStock: usa un parámetro mínimo de cinco unidades como umbral.
  • ObtenerValorTotalDeInventario: retorna un decimal con el valor acumulado.
  • ObtenerPrecioPromedio: calcula el promedio de precios.
  • ObtenerProductoMásCaro: retorna un producto con símbolo de nulabilidad para evitar excepciones.

¿Cómo funcionan los reportes y la persistencia?

Para generar reportes se instancia GeneradorReportes dentro de cada método correspondiente [3:54]. Los cuatro métodos de reporte son:

  • GenerarResumen: obtiene todos los productos y llama a generador.GenerarResumen().
  • GenerarReporteStockBajo: filtra con la condición de stock menor a cinco.
  • GenerarTopProductos: usa un parámetro inicial de cinco productos.
  • ExportarCSV: genera un archivo CSV con los datos del inventario.

El método privado _Persistir resuelve el error que el editor marca inicialmente [4:28]. Este método primero crea un backup con _storage.CrearBackup(), luego obtiene todos los productos del repositorio, los convierte a lista y finalmente los guarda en la ruta del inventario con storage.Guardar().

¿Cómo se construye el menú interactivo en Program.cs?

En Program.cs se inicializa el servicio y se usa un booleano para mantener activo el sistema [5:09]. Un ciclo while presenta al usuario diez opciones mediante un switch:

  1. Agregar producto.
  2. Listar productos.
  3. Buscar por ID.
  4. Eliminar producto.
  5. Buscar por categoría.
  6. Mostrar resumen.
  7. Mostrar stock bajo.
  8. Mostrar estadísticas.
  9. Exportar CSV.
  10. Salir del sistema.

El método MostrarMenú imprime las opciones con Console.WriteLine [5:52]. Cada caso lee la entrada del usuario con Console.ReadLine y la parsea al tipo correspondiente. Para las categorías se realiza un Enum.TryParse que valida la entrada o asigna la categoría "Otros" por defecto [6:30].

¿Qué sucede al probar la aplicación?

Al ejecutar dotnet run se despliega el menú completo [8:27]. La prueba demuestra:

  • Agregar un producto "Mac" con precio 1000, cantidad 4 y categoría electrónica.
  • Listarlo y verificar ID, nombre, precio, cantidad, total y categoría.
  • Buscarlo por ID y por categoría electrónica.
  • El resumen muestra el total de productos y valor del inventario.
  • El reporte de stock bajo incluye "Mac" porque tiene 4 unidades (menor al umbral de 5).
  • La exportación CSV respeta la estructura de columnas.
  • Eliminar el producto por ID y verificar que el inventario queda vacío.

Los datos persisten en inventario.json, lo que significa que al ejecutar la aplicación nuevamente los productos seguirán disponibles [9:43]. Los patrones aplicados durante todo el proyecto son Factory, Repository, Facade y persistencia JSON, formando una arquitectura profesional y extensible.

Si completaste el proyecto, comparte tu repositorio y compáralo con el release cinco disponible en los recursos.

      Facade y menú completo en C# con persistencia JSON