0% encontró este documento útil (0 votos)
2 vistas14 páginas

Version 2

La Clean Architecture se compone de cuatro capas: Entidades, que representan las reglas de negocio; Casos de Uso, que orquestan las acciones del negocio; Interfaces/Adaptadores, que conectan el mundo externo con la aplicación; y Frameworks y Drivers, que abarcan la infraestructura técnica. Cada capa tiene una función específica y las dependencias siempre apuntan hacia adentro, garantizando que las capas internas no conozcan detalles de las externas. En un proyecto .NET, se estructura en cuatro proyectos separados: Domain, Application, Infrastructure y WebApi, manteniendo así un diseño limpio y desacoplado.
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
2 vistas14 páginas

Version 2

La Clean Architecture se compone de cuatro capas: Entidades, que representan las reglas de negocio; Casos de Uso, que orquestan las acciones del negocio; Interfaces/Adaptadores, que conectan el mundo externo con la aplicación; y Frameworks y Drivers, que abarcan la infraestructura técnica. Cada capa tiene una función específica y las dependencias siempre apuntan hacia adentro, garantizando que las capas internas no conozcan detalles de las externas. En un proyecto .NET, se estructura en cuatro proyectos separados: Domain, Application, Infrastructure y WebApi, manteniendo así un diseño limpio y desacoplado.
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd

puedes explicarme cuales son las capas que componen Clean Architecture

Claro. La Clean Architecture organiza el sistema en capas concéntricas con


una regla clave: las dependencias siempre apuntan hacia adentro (las
capas externas dependen de las internas, nunca al revés).

Te lo explico de forma clara y útil 👇

🧠 1. Entidades (Entities)

Son el núcleo del sistema.

 Representan las reglas de negocio más puras.

 No dependen de nada externo (ni base de datos, ni frameworks).

 Ejemplo: Usuario, Pedido, Factura.

👉 Aquí vive la lógica crítica del negocio.

⚙️2. Casos de Uso (Use Cases / Application)

Aquí defines qué hace el sistema.

 Orquestan las acciones del negocio.

 Usan las entidades para ejecutar procesos.

 No conocen detalles técnicos (BD, UI, APIs).

Ejemplo:

 Crear usuario

 Procesar pago

 Generar reporte

👉 Son el “cerebro operativo”.

🔌 3. Interfaces / Adaptadores (Interface Adapters)

Conectan el mundo externo con tu aplicación.

 Transforman datos entre formatos (DTOs ↔ entidades).


 Incluyen:

o Controladores (Controllers)

o Presentadores

o Repositorios (interfaces)

Ejemplo:

 Convertir JSON de una API a objeto Usuario

 Mapear datos de BD a entidades

👉 Son traductores.

🌐 4. Frameworks y Drivers (Infraestructura)

Es la capa más externa.

 Todo lo técnico:

o Base de datos (SQL Server, MySQL)

o Frameworks (.NET, Spring, etc.)

o APIs externas

o UI (web, móvil)

👉 Aquí está lo reemplazable.

🔄 Regla clave (MUY IMPORTANTE)

Se llama Regla de Dependencia:

➡️Las capas externas dependen de las internas


❌ Las internas NO saben nada de las externas

🧩 Ejemplo sencillo

Imagina crear un usuario:

1. UI (Infraestructura) → recibe datos

2. Controller (Adapters) → los convierte


3. Use Case → ejecuta “Crear Usuario”

4. Entity → valida reglas (ej: edad válida)

🎯 Resumen rápido

Capa Rol

Reglas del
Entidades
negocio

Casos de Lógica de
uso aplicación

Traducción de
Adaptadores
datos

Infraestructu Tecnología
ra externa

Si quieres, puedo ayudarte a armar un proyecto real en .NET paso a


paso con estas capas, incluso usando Dapper como mencionaste antes.

Explicame cómo se estructura un proyecto en .NET con estas capas

Te lo explico de forma práctica, como si fueras a crearlo desde cero en .NET 👇


La idea es traducir la Clean Architecture a una solución real con varios
proyectos.

Estructura típica en .NET

En Visual Studio o CLI, se suele crear una solución así:

[Link]

├── [Link]
├── [Link]
├── [Link]
└── [Link] (o UI)
🧠 1. Domain (Entidades)

👉 Núcleo del sistema (NO depende de nadie)

Contenido:

 Entidades

 Value Objects

 Interfaces básicas (repositorios)

 Reglas de negocio

Ejemplo:

public class Usuario


{
public int Id { get; set; }
public string Nombre { get; set; }

public void Validar()


{
if ([Link](Nombre))
throw new Exception("El nombre es obligatorio");
}
}

🔑 Importante:

 ❌ Nada de Entity Framework

 ❌ Nada de Dapper

 ❌ Nada de HTTP

⚙️2. Application (Casos de Uso)

👉 Aquí vive la lógica de la aplicación

Contenido:

 Casos de uso (Services / Handlers)

 DTOs

 Interfaces de repositorio (si no están en Domain)


 Validaciones

Ejemplo:

public class CrearUsuarioUseCase


{
private readonly IUsuarioRepository _repo;

public CrearUsuarioUseCase(IUsuarioRepository repo)


{
_repo = repo;
}

public async Task Ejecutar(string nombre)


{
var usuario = new Usuario { Nombre = nombre };
[Link]();

await _repo.Crear(usuario);
}
}

🔌 3. Infrastructure (Infraestructura)

👉 Implementa lo técnico

Contenido:

 Repositorios reales (Dapper, EF)

 Acceso a base de datos

 Servicios externos

 Unit of Work

Ejemplo con Dapper:

public class UsuarioRepository : IUsuarioRepository


{
private readonly IDbConnection _connection;

public UsuarioRepository(IDbConnection connection)


{
_connection = connection;
}

public async Task Crear(Usuario usuario)


{
var sql = "INSERT INTO Usuarios (Nombre) VALUES (@Nombre)";
await _connection.ExecuteAsync(sql, usuario);
}
}

🌐 4. WebApi (o UI)

👉 Punto de entrada

Contenido:

 Controllers

 Configuración ([Link])

 Inyección de dependencias

Ejemplo:

[ApiController]
[Route("api/[controller]")]
public class UsuarioController : ControllerBase
{
private readonly CrearUsuarioUseCase _useCase;

public UsuarioController(CrearUsuarioUseCase useCase)


{
_useCase = useCase;
}

[HttpPost]
public async Task<IActionResult> Crear(string nombre)
{
await _useCase.Ejecutar(nombre);
return Ok();
}
}
🔗 Dependencias entre proyectos

MUY IMPORTANTE:

WebApi → Infrastructure → Application → Domain

Y también:

Infrastructure → Application
Application → Domain

❌ Domain NO depende de nadie


❌ Application NO depende de Infrastructure

🧩 Registro en [Link]

[Link]<IUsuarioRepository, UsuarioRepository>();
[Link]<CrearUsuarioUseCase>();

🎯 Flujo completo

1. Cliente llama API

2. Controller recibe datos

3. Use Case ejecuta lógica

4. Repository guarda en BD

5. Entity valida reglas

🚀 Tips importantes (esto marca la diferencia)

 Usa interfaces para desacoplar

 Mantén el Domain limpio

 No mezcles lógica de negocio con acceso a datos

 Usa DTOs para entrada/salida

 Puedes agregar:

o Application/Interfaces
o Application/DTOs

o Infrastructure/Persistence

Si quieres, en el siguiente paso puedo armarte:

✅ Un proyecto completo en .NET paso a paso


✅ Con Dapper + UnitOfWork (como el que ya tienes)
✅ CRUD automático SIN stored procedures

Solo dime 👍

Con Dapper + UnitOfWork (como el que ya tienes) y tambien incluye


IUsuarioRepository ya que lo usaste pero no lo definiste?

Perfecto, vamos a armarte una base real y lista para usar con Dapper +
Unit of Work + IUsuarioRepository, siguiendo la Clean Architecture.

Te dejo todo conectado y coherente 👇

Estructura final

[Link]

├── [Link]
├── [Link]
├── [Link]
└── [Link]

🧠 1. DOMAIN

✅ Entidad

public class Usuario


{
public int Id { get; set; }
public string Nombre { get; set; }

public void Validar()


{
if ([Link](Nombre))
throw new Exception("El nombre es obligatorio");
}
}

✅ Interface del repositorio

👉 Aquí defines el contrato

public interface IUsuarioRepository


{
Task Crear(Usuario usuario);
Task<Usuario?> ObtenerPorId(int id);
Task<IEnumerable<Usuario>> ObtenerTodos();
Task Actualizar(Usuario usuario);
Task Eliminar(int id);
}

⚙️2. APPLICATION

✅ Caso de uso

public class UsuarioService


{
private readonly IUsuarioRepository _repo;

public UsuarioService(IUsuarioRepository repo)


{
_repo = repo;
}

public async Task Crear(string nombre)


{
var usuario = new Usuario { Nombre = nombre };
[Link]();

await _repo.Crear(usuario);
}

public Task<IEnumerable<Usuario>> ObtenerTodos()


=> _repo.ObtenerTodos();
}

🔌 3. INFRASTRUCTURE

Aquí metemos Dapper + UnitOfWork + Repository

✅ Unit of Work (clave)

public interface IUnitOfWork : IDisposable


{
IDbTransaction Transaction { get; }
IDbConnection Connection { get; }

Task BeginTransactionAsync();
Task CommitAsync();
Task RollbackAsync();
}

✅ Implementación UnitOfWork

public class UnitOfWork : IUnitOfWork


{
private readonly IDbConnection _connection;
private IDbTransaction _transaction;

public IDbConnection Connection => _connection;


public IDbTransaction Transaction => _transaction;

public UnitOfWork(IDbConnection connection)


{
_connection = connection;
}

public async Task BeginTransactionAsync()


{
if (_connection.State != [Link])
_connection.Open();
_transaction = _connection.BeginTransaction();
await [Link];
}

public async Task CommitAsync()


{
_transaction?.Commit();
await [Link];
}

public async Task RollbackAsync()


{
_transaction?.Rollback();
await [Link];
}

public void Dispose()


{
_transaction?.Dispose();
_connection?.Dispose();
}
}

✅ UsuarioRepository (Dapper)

using Dapper;

public class UsuarioRepository : IUsuarioRepository


{
private readonly IUnitOfWork _uow;

public UsuarioRepository(IUnitOfWork uow)


{
_uow = uow;
}

public async Task Crear(Usuario usuario)


{
var sql = "INSERT INTO Usuarios (Nombre) VALUES (@Nombre)";
await _uow.[Link](sql, usuario, _uow.Transaction);
}

public async Task<Usuario?> ObtenerPorId(int id)


{
var sql = "SELECT * FROM Usuarios WHERE Id = @Id";
return await _uow.[Link]<Usuario>(
sql, new { Id = id }, _uow.Transaction);
}

public async Task<IEnumerable<Usuario>> ObtenerTodos()


{
var sql = "SELECT * FROM Usuarios";
return await _uow.[Link]<Usuario>(
sql, transaction: _uow.Transaction);
}

public async Task Actualizar(Usuario usuario)


{
var sql = "UPDATE Usuarios SET Nombre = @Nombre WHERE Id = @Id";
await _uow.[Link](sql, usuario, _uow.Transaction);
}

public async Task Eliminar(int id)


{
var sql = "DELETE FROM Usuarios WHERE Id = @Id";
await _uow.[Link](sql, new { Id = id },
_uow.Transaction);
}
}

🌐 4. WEB API

✅ Controller

[ApiController]
[Route("api/[controller]")]
public class UsuarioController : ControllerBase
{
private readonly UsuarioService _service;
private readonly IUnitOfWork _uow;

public UsuarioController(UsuarioService service, IUnitOfWork uow)


{
_service = service;
_uow = uow;
}

[HttpPost]
public async Task<IActionResult> Crear(string nombre)
{
await _uow.BeginTransactionAsync();

try
{
await _service.Crear(nombre);
await _uow.CommitAsync();

return Ok();
}
catch (Exception ex)
{
await _uow.RollbackAsync();
return BadRequest([Link]);
}
}

[HttpGet]
public async Task<IActionResult> Obtener()
{
var data = await _service.ObtenerTodos();
return Ok(data);
}
}

🔗 [Link] (DI)
[Link]<IDbConnection>(sp =>
new SqlConnection([Link]("Default")));

[Link]<IUnitOfWork, UnitOfWork>();
[Link]<IUsuarioRepository, UsuarioRepository>();
[Link]<UsuarioService>();

🔄 Flujo real con transacción

1. Controller inicia transacción

2. Service ejecuta lógica

3. Repository usa Dapper

4. UnitOfWork controla commit/rollback

🚀 Mejora PRO (muy recomendada)

Puedes evolucionar esto a:

 UnitOfWorkFactory

 BaseRepository

 Manejo automático de transacciones (middleware)

 CQRS (separar lectura/escritura)

Si quieres, en el siguiente paso te puedo armar:

✅ Proyecto completo descargable


✅ CRUD genérico reutilizable
✅ Paginación + filtros
✅ Manejo de errores profesional

También podría gustarte