DeutschLernen/GermanApp/Application/UseCases/Commands/CreateLessonCommand.cs
Lasse Rune Hansen d90e4792d6 Initial commit: GermanApp with Clean Architecture
- Domain layer: Lesson entity, GermanWord value object, repository interfaces
- Application layer: CQRS commands, DTOs with mapping
- Infrastructure layer: EF Core with SQLite, LessonRepository
- Presentation layer: Minimal API endpoints for lessons CRUD

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
2026-05-31 18:14:51 +02:00

65 lines
2 KiB
C#

using GermanApp.Application.DTOs;
using GermanApp.Domain.Entities;
using GermanApp.Domain.Exceptions;
using GermanApp.Domain.Interfaces;
namespace GermanApp.Application.UseCases.Commands;
/// <summary>
/// Command for creating a new lesson.
/// This follows the CQRS pattern - commands represent write operations.
/// </summary>
public record CreateLessonCommand(CreateLessonDto LessonData) : ICommand<LessonDto>;
/// <summary>
/// Handler for the CreateLessonCommand.
/// </summary>
public class CreateLessonCommandHandler : ICommandHandler<CreateLessonCommand, LessonDto>
{
private readonly ILessonRepository _lessonRepository;
public CreateLessonCommandHandler(ILessonRepository lessonRepository)
{
_lessonRepository = lessonRepository;
}
public async Task<LessonDto> Handle(CreateLessonCommand command, CancellationToken cancellationToken)
{
// Convert DTO to domain entity
var lesson = command.LessonData.ToEntity();
// Validate business rules (could be extracted to a validator)
if (lesson.Level < 1 || lesson.Level > 5)
{
throw new ValidationException("Level must be between 1 and 5");
}
// Add to repository
var createdLesson = await _lessonRepository.AddAsync(lesson, cancellationToken);
// Return DTO representation
return createdLesson.ToDto();
}
}
/// <summary>
/// Generic command interface.
/// </summary>
/// <typeparam name="TResult">The result type</typeparam>
public interface ICommand<out TResult>
{
}
/// <summary>
/// Generic command handler interface.
/// </summary>
/// <typeparam name="TCommand">The command type</typeparam>
/// <typeparam name="TResult">The result type</typeparam>
public interface ICommandHandler<in TCommand, TResult>
where TCommand : ICommand<TResult>
{
Task<TResult> Handle(TCommand command, CancellationToken cancellationToken);
}
// Note: For MediatR integration, you would implement IRequestHandler<TCommand, TResult>
// instead of the custom interfaces above.