Hola, recién estoy implementando la arquitectura CLEAN en mis proyectos de .NET y tengo una duda con respecto a la reutilización de Commands y/o Queries.
Supongamos que tengo los siguientes comandos (con su respectivo handler que no pongo por brevedad):
// Permite crear un usuario.
public class CreateUserCommand : IRequest<int>
{
public string Name { get; set; }
public string Email { get; set; }
}
// Permite crear un contacto a un usuario.
public class CreateContactCommand : IRequest<int>
{
public int UserId { get; set; }
public string Name { get; set; }
public string Number { get; set; }
}
Hasta el momento cada uno de estos comandos funcionan independientemente y sin ninguna novedad, pero digamos que me llegó un requerimiento donde me solicitan que se pueda importar desde un JSON los usuarios y sus contactos. Entonces considero hacer un comando que internamente en su lógica use los otros dos comandos, algo así:
public class UserDto
{
public string Name { get; set; }
public string Email { get; set; }
public List<ContactDto> Contacts { get; set; }
}
public class ContactDto
{
public string Name { get; set; }
public string Number { get; set; }
}
public class ImportUsersCommand : IRequest<int>
{
public List<UserDto> ImportData { get; set; }
}
public class ImportUsersCommandHandler : IRequestHandler<ImportUsersCommand, int>
{
private readonly ISender _sender;
public ImportUsersCommandHandler(ISender sender) { _sender = sender }
public async Task<int> Handle(ImportUsersCommand request, CancellationToken cancellationToken)
{
foreach(var user in request.Users)
{
int userId = await _sender.Send(new CreateUserCommand() { Name = request.Name, Email = request.Email });
// Luego otro foreach pero utilizando el comando CreateContactCommand
}
return userId;
}
}
¿Esto lo puedo hacer en esta arquitectura?
A priori:
- El principio DRY me dice que debería reutilizar lógica que ya existe.
- Pero el principio de Single Responsability me dice que cada comando debería trabajar de forma independiente, por lo que el handler de
ImportUsersCommand
debería encargarse de todo por si solo.
Como dato adicional, me estoy basando en esta plantilla CleanArchitecture y estoy usando MediatR para el trabajo de CQRS.
¿Qué opinas?, si tienes experiencia en el tema no dudes en comentar.