```csharp // DinnerPlanner.API (ASP.NET Core Web API) // Domain Layer (DDD Core) public class Recipe : Entity { public string Name { get; private set; } public string Description { get; private set; } public string Instructions { get; private set; } private readonly List _ingredients = new(); public IReadOnlyCollection Ingredients => _ingredients.AsReadOnly(); private readonly List _tags = new(); public IReadOnlyCollection Tags => _tags.AsReadOnly(); private Recipe() { } // For EF Core public Recipe(string name, string description, string instructions) { Id = Guid.NewGuid(); Name = name; Description = description; Instructions = instructions; } public void AddIngredient(string name) { _ingredients.Add(new Ingredient(name)); } public void AddTag(string name) { _tags.Add(new Tag(name)); } } public class Ingredient : ValueObject { public string Name { get; } public Ingredient(string name) { Name = name; } protected override IEnumerable GetEqualityComponents() { yield return Name; } } public class Tag : ValueObject { public string Name { get; } public Tag(string name) { Name = name; } protected override IEnumerable GetEqualityComponents() { yield return Name; } } // Application Layer (MediatR Handlers) public class GetRecipesQuery : IRequest> { } public class GetRecipesQueryHandler : IRequestHandler> { private readonly IRecipeRepository _repository; public GetRecipesQueryHandler(IRecipeRepository repository) { _repository = repository; } public async Task> Handle(GetRecipesQuery request, CancellationToken cancellationToken) { var recipes = await _repository.GetAllAsync(); return recipes.Select(r => new RecipeDto { Id = r.Id, Name = r.Name, Description = r.Description, Ingredients = r.Ingredients.Select(i => i.Name).ToList(), Instructions = r.Instructions, Tags = r.Tags.Select(t => t.Name).ToList() }).ToList(); } } // Infrastructure Layer (EF Core) public class RecipeRepository : IRecipeRepository { private readonly DinnerPlannerDbContext _context; public RecipeRepository(DinnerPlannerDbContext context) { _context = context; } public async Task AddAsync(Recipe recipe) { await _context.Recipes.AddAsync(recipe); await _context.SaveChangesAsync(); } public async Task> GetAllAsync() { return await _context.Recipes .Include(r => r.Ingredients) .Include(r => r.Tags) .ToListAsync(); } } // API Layer (Controllers) [ApiController] [Route("api/[controller]")] public class RecipesController : ControllerBase { private readonly IMediator _mediator; public RecipesController(IMediator mediator) { _mediator = mediator; } [HttpGet] public async Task>> Get() { var recipes = await _mediator.Send(new GetRecipesQuery()); return Ok(recipes); } [HttpPost] public async Task> Create(CreateRecipeCommand command) { var recipe = await _mediator.Send(command); return CreatedAtAction(nameof(Get), new { id = recipe.Id }, recipe); } } // Startup Configuration public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddDbContext(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); services.AddScoped(); services.AddMediatR(typeof(GetRecipesQueryHandler)); services.AddControllers(); services.AddSwaggerGen(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseRouting(); app.UseEndpoints(endpoints => endpoints.MapControllers()); app.UseSwagger(); app.UseSwaggerUI(); } } ```