Blazor · Ejercicio guiado
Te damos una aplicación Blazor separada en tres capas (Domain, BusinessLogic y Web) que ya funciona: lista usuarios y permite dar de alta nuevos. Tu trabajo es leer el código, encontrar qué está mal en cómo el frontend usa los datos, y corregirlo con un DTO y un mapper.
LabDTO-inicial.zipdotnet --version # tiene que empezar con 9
LabDTO.sln · tres proyectos
Descomprimí LabDTO-inicial.zip. En Rider elegí y abrí el archivo LabDTO.sln.
En el panel de la izquierda vas a ver tres proyectos, uno por capa. Arriba a la derecha, en la lista de configuraciones de ejecución, elegí LabDTO.Web y dale ▶ Run. La app queda en una dirección fija:
http://localhost:5080
antes de tocar nada, entender qué hay
Entrá a Usuarios desde el menú. Mirá la tabla y agregá un usuario con el formulario de abajo.
La solución está separada en capas. Cada flecha es una referencia entre proyectos: el de la izquierda puede usar las clases del de la derecha.
LabDTO.Web ──▶ LabDTO.BusinessLogic ──▶ LabDTO.Domain (frontend) (lógica de negocio) (entidades) LabDTO.Domain/Usuario.cs la entidad de dominio LabDTO.BusinessLogic/UsuarioServicio.cs lista y agrega usuarios LabDTO.Web/Components/Pages/Usuarios.razor la página que acabás de usar
Abrí esos tres archivos en Rider y leelos con calma. Después respondan estas preguntas. No hace falta que estén seguros: escriban lo que piensan.
| Pregunta | Respuesta del grupo |
|---|---|
| ¿Qué datos de cada usuario muestra la página? ¿Alguno no debería verse? | |
En Usuarios.razor, ¿qué @using hay arriba? ¿De qué proyecto viene la clase que recorre la tabla? | |
| El proyecto Web solo referencia a BusinessLogic. ¿Cómo puede entonces usar una clase de Domain? | |
| Cuando agregás un usuario, ¿quién decide su contraseña? ¿En qué capa está esa decisión? | |
Si mañana en Usuario renombran Email a Correo, ¿qué proyectos dejan de compilar? |
en BusinessLogic, con solo lo que el frontend necesita
Click derecho sobre el proyecto LabDTO.BusinessLogic → , nombre Dtos. Dentro de esa carpeta, , nombre UsuarioDto. Reemplazá el contenido por esto y resolvé el TODO 1:
namespace LabDTO.BusinessLogic.Dtos;
// TODO 1: agregá las propiedades que el frontend necesita.
// Usá las respuestas del paso 1 para decidir qué entra y qué queda afuera.
public class UsuarioDto
{
}
Usuario se queda adentro de BusinessLogic. Eso nos sirve para dos cosas:
dotnet build # tiene que terminar en "Build succeeded."
traducir entidad ⇄ DTO, a mano
Ahora tenemos dos clases que representan a un usuario: la entidad Usuario, que usa BusinessLogic por dentro, y el UsuarioDto, que es lo que viaja hacia el frontend. Alguien tiene que encargarse de pasar los datos de una a la otra, en los dos sentidos: de entidad a DTO cuando el servicio entrega usuarios, y de DTO a entidad cuando recibe uno nuevo.
Esa responsabilidad no le corresponde al DTO. Como vimos, el DTO es solo un contenedor de datos, sin lógica: si le agregáramos métodos para convertirse, tendría que conocer la entidad de dominio, y eso es justo lo que queremos evitar. Tampoco le corresponde a la página, que no debería saber que la entidad existe. Por eso la ponemos en una clase aparte, dedicada solo a eso: el mapper. Así toda la traducción entre las dos clases queda en un único lugar.
En LabDTO.BusinessLogic creá la carpeta Mappers y adentro la clase UsuarioMapper. Reemplazá el contenido por esto y resolvé los TODO 2 y 3:
using LabDTO.BusinessLogic.Dtos;
using LabDTO.Domain;
namespace LabDTO.BusinessLogic.Mappers;
public static class UsuarioMapper
{
public static UsuarioDto ToDto(Usuario usuario)
{
// TODO 2: devolvé un UsuarioDto con los datos de "usuario"
}
public static Usuario ToEntity(UsuarioDto dto)
{
// TODO 3: devolvé un Usuario armado con los datos de "dto".
// El DTO no trae contraseña: buscá en el código actual qué contraseña
// reciben los usuarios nuevos y mové esa decisión acá.
}
}
new Tipo { Propiedad = origen.Propiedad, ... }. Los métodos de una clase static se llaman con el nombre de la clase, sin crear una instancia.
dotnet build # tiene que terminar en "Build succeeded."
Usuario y UsuarioDto.
BusinessLogic deja de entregar la entidad
Abrí UsuarioServicio.cs. Por dentro el servicio sigue guardando entidades Usuario, pero hacia afuera tiene que entregar y recibir DTOs.
Listar() devuelva una lista de UsuarioDto, convirtiendo cada usuario con el mapper.Agregar(...) reciba un UsuarioDto y lo convierta a entidad antes de guardarlo..Select(...) transforma cada elemento de una lista en otra cosa: le podés pasar directamente un método que reciba un elemento y devuelva el nuevo. Para que el resultado sea una lista, terminá con .ToList().
dotnet build
LabDTO.BusinessLogic compila, pero LabDTO.Web no: la página falla en los lugares donde usaba la entidad. Leé los errores antes de seguir.
el frontend deja de conocer el dominio
Abrí Usuarios.razor. TODO 6: hacé que compile de nuevo trabajando con UsuarioDto: la tabla sin columna de contraseña, y el alta armando un DTO en vez de una entidad. La página no tiene que decidir ninguna contraseña.
@using del dominio por el de la carpeta de DTOs. La página ya no necesita el mapper: la conversión ahora la hace el servicio.
Antes de terminar, probá escribir @u.Password en alguna celda de la tabla y mirá qué marca Rider. Después sacalo. ■ Stop y ▶ Run para probar la página.
Usuarios.razor ya no tiene @using LabDTO.Domain ni nombra la entidad Usuario en ningún lado.
Email a Correo en Usuario, ¿qué proyectos dejan de compilar? Y otra: borraste el @using, pero Web sigue referenciando a BusinessLogic, que referencia a Domain. ¿Qué le impide a alguien volver a usar Usuario en la página?
Id, si el Id lo pone el servicio? Creá un UsuarioAltaDto solo con lo que se carga en el formulario, y su método en el mapper.