Clean Architecture en .NET

La Arquitectura Limpia (Clean Architecture) es un enfoque que busca crear aplicaciones independientes de frameworks, bases de datos y detalles de implementación. Este enfoque ayuda a desarrollar software que es fácil de entender, probar y mantener. En este artículo, exploraremos los conceptos básicos de la Arquitectura Limpia en .NET y cómo implementarlos en un proyecto.

1. ¿Qué es la Arquitectura Limpia?

La Arquitectura Limpia fue popularizada por Robert C. Martin (también conocido como Uncle Bob). Su objetivo es separar las preocupaciones de una aplicación en diferentes capas, permitiendo que cada capa sea independiente. Esto facilita la prueba de cada componente de manera aislada y la evolución del software sin introducir dependencias indeseadas.

1.1. Capas de la Arquitectura Limpia

En términos generales, la Arquitectura Limpia se compone de varias capas:

  • Capa de Presentación: Interfaz de usuario, donde los usuarios interactúan con la aplicación.
  • Capa de Aplicación: Contiene la lógica de la aplicación y los casos de uso.
  • Capa de Dominio: Contiene las entidades de negocio y la lógica relacionada.
  • Capa de Infraestructura: Implementaciones específicas como bases de datos, APIs externas, etc.

Clean Architecture Layers

2. Implementación de Clean Architecture en .NET

Vamos a crear una simple aplicación de gestión de tareas utilizando la Arquitectura Limpia.

2.1. Estructura del Proyecto

Crea un proyecto con la siguiente estructura de carpetas:

/MyProjectName
  /MyProjectName.Api      // Capa de Presentación
  /MyProjectName.Application // Capa de Aplicación
  /MyProjectName.Domain    // Capa de Dominio
  /MyProjectName.Infrastructure // Capa de Infraestructura

2.2. Capa de Dominio

La capa de dominio contiene las entidades y la lógica de negocio.

// MyProjectName.Domain/TodoItem.cs
namespace MyProjectName.Domain
{
    public class TodoItem
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public bool IsCompleted { get; set; }
    }
}

2.3. Capa de Aplicación

La capa de aplicación contiene los casos de uso y la lógica relacionada.

// MyProjectName.Application/ITodoService.cs
using MyProjectName.Domain;
using System.Collections.Generic;

namespace MyProjectName.Application
{
    public interface ITodoService
    {
        IEnumerable<TodoItem> GetAllTodos();
        void AddTodo(TodoItem todo);
    }
}

// MyProjectName.Application/TodoService.cs
using MyProjectName.Domain;
using System.Collections.Generic;

namespace MyProjectName.Application
{
    public class TodoService : ITodoService
    {
        private readonly List<TodoItem> _todos = new List<TodoItem>();

        public IEnumerable<TodoItem> GetAllTodos() => _todos;

        public void AddTodo(TodoItem todo)
        {
            todo.Id = _todos.Count + 1; // Simulando un ID
            _todos.Add(todo);
        }
    }
}

2.4. Capa de Infraestructura

La capa de infraestructura se encarga de las dependencias externas, como bases de datos o APIs.

// MyProjectName.Infrastructure/TodoRepository.cs
using MyProjectName.Domain;
using System.Collections.Generic;

namespace MyProjectName.Infrastructure
{
    public class TodoRepository
    {
        private readonly List<TodoItem> _todos = new List<TodoItem>();

        public IEnumerable<TodoItem> GetAll() => _todos;

        public void Add(TodoItem todo)
        {
            todo.Id = _todos.Count + 1; // Simulando un ID
            _todos.Add(todo);
        }
    }
}

2.5. Capa de Presentación

La capa de presentación es donde se interactúa con la aplicación. En este caso, usaremos una API ASP.NET Core.

// MyProjectName.Api/Controllers/TodoController.cs
using MyProjectName.Application;
using MyProjectName.Domain;
using Microsoft.AspNetCore.Mvc;

namespace MyProjectName.Api.Controllers
{
    [ApiController]
    [Route("api/todos")]
    public class TodoController : ControllerBase
    {
        private readonly ITodoService _todoService;

        public TodoController(ITodoService todoService)
        {
            _todoService = todoService;
        }

        [HttpGet]
        public IActionResult GetAll()
        {
            return Ok(_todoService.GetAllTodos());
        }

        [HttpPost]
        public IActionResult Add(TodoItem todo)
        {
            _todoService.AddTodo(todo);
            return CreatedAtAction(nameof(GetAll), new { id = todo.Id }, todo);
        }
    }
}

3. Inyección de Dependencias

No olvides registrar los servicios en el contenedor de dependencias. Esto se hace en Startup.cs:

// MyProjectName.Api/Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    services.AddScoped<ITodoService, TodoService>(); // Registro de la capa de aplicación
}

4. Ventajas de la Arquitectura Limpia

  1. Independencia: Las capas están separadas, lo que facilita el mantenimiento y la evolución.
  2. Testabilidad: Cada capa se puede probar de manera aislada.
  3. Flexibilidad: Se pueden cambiar las implementaciones de infraestructura sin afectar el dominio.

5. Conclusiones

La Arquitectura Limpia proporciona un enfoque robusto para el desarrollo de software en .NET. Al seguir sus principios, puedes crear aplicaciones que son fáciles de mantener y evolucionar a lo largo del tiempo.


Referencias