From 7d11eaf7efabeb15b14f1d923d68d1df2881ed3b Mon Sep 17 00:00:00 2001 From: franc Date: Tue, 15 Apr 2025 16:10:42 +0200 Subject: [PATCH 1/6] Implement two methods for the sorting logic on the service --- .../Instruction/IInstructionRepository.cs | 4 ++ .../Instruction/InstructionRepository.cs | 39 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/Francesco.Recipes.World/Repositories/Instruction/IInstructionRepository.cs b/Francesco.Recipes.World/Repositories/Instruction/IInstructionRepository.cs index 963099b..528f6b8 100644 --- a/Francesco.Recipes.World/Repositories/Instruction/IInstructionRepository.cs +++ b/Francesco.Recipes.World/Repositories/Instruction/IInstructionRepository.cs @@ -11,5 +11,9 @@ Task> GetInstructionsByRecipeIdAsync(Guid recipeId); Task RemoveInstructionFromRecipeAsync(Guid recipeId, Guid instructionId); + + Task SwapInstructionOrderAsync(Instruction a, Instruction b); + + Task GetInstructionWithRecipeAsync(Guid instructionId); } } diff --git a/Francesco.Recipes.World/Repositories/Instruction/InstructionRepository.cs b/Francesco.Recipes.World/Repositories/Instruction/InstructionRepository.cs index b487d57..0a71b5f 100644 --- a/Francesco.Recipes.World/Repositories/Instruction/InstructionRepository.cs +++ b/Francesco.Recipes.World/Repositories/Instruction/InstructionRepository.cs @@ -77,5 +77,44 @@ .Where(i => i.Recipe.Id == recipeId) .ToListAsync(); } + + public async Task GetInstructionWithRecipeAsync(Guid instructionId) + { + var instruction = await _context.Instructions + .Include(i => i.Recipe) + .ThenInclude(r => r.Instructions) + .FirstOrDefaultAsync(i => i.Id == instructionId); + + if (instruction == null) + { + throw new InvalidDataException($"Instruction with ID {instructionId} not found."); + } + + if (instruction.Recipe == null) + { + throw new InvalidDataException($"The Recipe for Instruction with ID {instructionId} is not loaded or does not exist."); + } + + return instruction; + } + + public async Task SwapInstructionOrderAsync(Instruction a, Instruction b) + { + if (a == null) + { + throw new ArgumentNullException(nameof(a), "Instruction 'a' cannot be null."); + } + + if (b == null) + { + throw new ArgumentNullException(nameof(b), "Instruction 'b' cannot be null."); + } + + var temp = a.Number; + a.Number = b.Number; + b.Number = temp; + + await _context.SaveChangesAsync(); + } } } From 71ebfcf4bee42b279c74490aaa4d86b96544ca1a Mon Sep 17 00:00:00 2001 From: franc Date: Tue, 15 Apr 2025 16:11:07 +0200 Subject: [PATCH 2/6] Implement the Sorting Logic --- .../Instruction/IInstructionService.cs | 9 ++++ .../Instruction/InstructionService.cs | 54 +++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 Francesco.Recipes.World/Services/Instruction/IInstructionService.cs create mode 100644 Francesco.Recipes.World/Services/Instruction/InstructionService.cs diff --git a/Francesco.Recipes.World/Services/Instruction/IInstructionService.cs b/Francesco.Recipes.World/Services/Instruction/IInstructionService.cs new file mode 100644 index 0000000..fa514a1 --- /dev/null +++ b/Francesco.Recipes.World/Services/Instruction/IInstructionService.cs @@ -0,0 +1,9 @@ +namespace Francesco.Recipes.World.Services.Instruction +{ + public interface IInstructionService + { + Task MoveInstructionUpAsync(Guid instructionId); + + Task MoveInstructionDownAsync(Guid instructionId); + } +} diff --git a/Francesco.Recipes.World/Services/Instruction/InstructionService.cs b/Francesco.Recipes.World/Services/Instruction/InstructionService.cs new file mode 100644 index 0000000..5015426 --- /dev/null +++ b/Francesco.Recipes.World/Services/Instruction/InstructionService.cs @@ -0,0 +1,54 @@ +using Francesco.Recipes.World.Repositories.Instruction; + +namespace Francesco.Recipes.World.Services.Instruction +{ + public class InstructionService : IInstructionService + { + private readonly IInstructionRepository _instructionRepository; + + public InstructionService(IInstructionRepository instructionRepository) + { + _instructionRepository = instructionRepository; + } + + public async Task MoveInstructionDownAsync(Guid instructionId) + { + var instruction = await _instructionRepository.GetInstructionWithRecipeAsync(instructionId); + + var instructions = await _instructionRepository.GetInstructionsByRecipeIdAsync(instruction.Recipe.Id); + + var maxStep = instructions.Max(i => i.Number); + + if (instruction.Number >= maxStep) + { + return; + } + + var neighbor = instructions.FirstOrDefault(i => i.Number == instruction.Number + 1); + + if (neighbor != null) + { + await _instructionRepository.SwapInstructionOrderAsync(instruction, neighbor); + } + } + + public async Task MoveInstructionUpAsync(Guid instructionId) + { + var instruction = await _instructionRepository.GetInstructionWithRecipeAsync(instructionId); + + if (instruction.Number == 1) + { + return; + } + + var instructions = await _instructionRepository.GetInstructionsByRecipeIdAsync(instruction.Recipe.Id); + + var neighbor = instructions.FirstOrDefault(i => i.Number == instruction.Number - 1); + + if (neighbor != null) + { + await _instructionRepository.SwapInstructionOrderAsync(instruction, neighbor); + } + } + } +} From 4b084eea9879a8af1ebf0b50dd148e26851dffa8 Mon Sep 17 00:00:00 2001 From: franc Date: Wed, 16 Apr 2025 17:22:19 +0200 Subject: [PATCH 3/6] Refactoring some code and change logic and make sure to reduce db calls and avoid redundants --- .../Instruction/IInstructionRepository.cs | 4 +- .../Instruction/InstructionRepository.cs | 21 ++-------- .../Instruction/IInstructionService.cs | 2 + .../Instruction/InstructionService.cs | 42 ++++++++----------- 4 files changed, 25 insertions(+), 44 deletions(-) diff --git a/Francesco.Recipes.World/Repositories/Instruction/IInstructionRepository.cs b/Francesco.Recipes.World/Repositories/Instruction/IInstructionRepository.cs index 528f6b8..057eb02 100644 --- a/Francesco.Recipes.World/Repositories/Instruction/IInstructionRepository.cs +++ b/Francesco.Recipes.World/Repositories/Instruction/IInstructionRepository.cs @@ -8,12 +8,10 @@ Task CreateInstructionToRecipeAsync(Guid recipeId, string description, int number); - Task> GetInstructionsByRecipeIdAsync(Guid recipeId); - Task RemoveInstructionFromRecipeAsync(Guid recipeId, Guid instructionId); Task SwapInstructionOrderAsync(Instruction a, Instruction b); - Task GetInstructionWithRecipeAsync(Guid instructionId); + Task> GetInstructionsByInstructionIdAsync(Guid instructionId); } } diff --git a/Francesco.Recipes.World/Repositories/Instruction/InstructionRepository.cs b/Francesco.Recipes.World/Repositories/Instruction/InstructionRepository.cs index 0a71b5f..a95e22d 100644 --- a/Francesco.Recipes.World/Repositories/Instruction/InstructionRepository.cs +++ b/Francesco.Recipes.World/Repositories/Instruction/InstructionRepository.cs @@ -70,32 +70,19 @@ } } - public async Task> GetInstructionsByRecipeIdAsync(Guid recipeId) - { - return await _context.Instructions - .Include(i => i.Recipe) - .Where(i => i.Recipe.Id == recipeId) - .ToListAsync(); - } - - public async Task GetInstructionWithRecipeAsync(Guid instructionId) + public async Task> GetInstructionsByInstructionIdAsync(Guid instructionId) { var instruction = await _context.Instructions .Include(i => i.Recipe) .ThenInclude(r => r.Instructions) .FirstOrDefaultAsync(i => i.Id == instructionId); - if (instruction == null) + if (instruction?.Recipe == null) { - throw new InvalidDataException($"Instruction with ID {instructionId} not found."); + throw new InvalidDataException($"Instruction with ID {instructionId} or its Recipe not found."); } - if (instruction.Recipe == null) - { - throw new InvalidDataException($"The Recipe for Instruction with ID {instructionId} is not loaded or does not exist."); - } - - return instruction; + return instruction.Recipe.Instructions.ToList(); } public async Task SwapInstructionOrderAsync(Instruction a, Instruction b) diff --git a/Francesco.Recipes.World/Services/Instruction/IInstructionService.cs b/Francesco.Recipes.World/Services/Instruction/IInstructionService.cs index fa514a1..efb6b00 100644 --- a/Francesco.Recipes.World/Services/Instruction/IInstructionService.cs +++ b/Francesco.Recipes.World/Services/Instruction/IInstructionService.cs @@ -5,5 +5,7 @@ Task MoveInstructionUpAsync(Guid instructionId); Task MoveInstructionDownAsync(Guid instructionId); + + Task MoveInstructionAsync(Guid instructionId, bool moveUp); } } diff --git a/Francesco.Recipes.World/Services/Instruction/InstructionService.cs b/Francesco.Recipes.World/Services/Instruction/InstructionService.cs index 5015426..895cf66 100644 --- a/Francesco.Recipes.World/Services/Instruction/InstructionService.cs +++ b/Francesco.Recipes.World/Services/Instruction/InstructionService.cs @@ -11,39 +11,33 @@ namespace Francesco.Recipes.World.Services.Instruction _instructionRepository = instructionRepository; } - public async Task MoveInstructionDownAsync(Guid instructionId) + public Task MoveInstructionUpAsync(Guid instructionId) + => MoveInstructionAsync(instructionId, moveUp: true); + + public Task MoveInstructionDownAsync(Guid instructionId) + => MoveInstructionAsync(instructionId, moveUp: false); + + private async Task MoveInstructionAsync(Guid instructionId, bool moveUp) { - var instruction = await _instructionRepository.GetInstructionWithRecipeAsync(instructionId); + var instructions = await _instructionRepository.GetInstructionsByInstructionIdAsync(instructionId); - var instructions = await _instructionRepository.GetInstructionsByRecipeIdAsync(instruction.Recipe.Id); + var instruction = instructions.FirstOrDefault(i => i.Id == instructionId); + if (instruction == null) + { + throw new InvalidDataException($"Instruction with ID {instructionId} not found."); + } + + var minStep = 1; var maxStep = instructions.Max(i => i.Number); - if (instruction.Number >= maxStep) + if ((moveUp && instruction.Number == minStep) || (!moveUp && instruction.Number >= maxStep)) { return; } - var neighbor = instructions.FirstOrDefault(i => i.Number == instruction.Number + 1); - - if (neighbor != null) - { - await _instructionRepository.SwapInstructionOrderAsync(instruction, neighbor); - } - } - - public async Task MoveInstructionUpAsync(Guid instructionId) - { - var instruction = await _instructionRepository.GetInstructionWithRecipeAsync(instructionId); - - if (instruction.Number == 1) - { - return; - } - - var instructions = await _instructionRepository.GetInstructionsByRecipeIdAsync(instruction.Recipe.Id); - - var neighbor = instructions.FirstOrDefault(i => i.Number == instruction.Number - 1); + var targetNumber = moveUp ? instruction.Number - 1 : instruction.Number + 1; + var neighbor = instructions.FirstOrDefault(i => i.Number == targetNumber); if (neighbor != null) { From b7706de30c8db5b590caebbc76dee7ea42f5e8d7 Mon Sep 17 00:00:00 2001 From: franc Date: Wed, 16 Apr 2025 17:27:08 +0200 Subject: [PATCH 4/6] Remove the interface declaration for MoveInstructionAsync since it's now a private method --- .../Services/Instruction/IInstructionService.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Francesco.Recipes.World/Services/Instruction/IInstructionService.cs b/Francesco.Recipes.World/Services/Instruction/IInstructionService.cs index efb6b00..8ddedf5 100644 --- a/Francesco.Recipes.World/Services/Instruction/IInstructionService.cs +++ b/Francesco.Recipes.World/Services/Instruction/IInstructionService.cs @@ -6,6 +6,5 @@ Task MoveInstructionDownAsync(Guid instructionId); - Task MoveInstructionAsync(Guid instructionId, bool moveUp); } } From 032e2caf1b956be574d3844517f777ec5cda5e57 Mon Sep 17 00:00:00 2001 From: franc Date: Wed, 16 Apr 2025 17:27:41 +0200 Subject: [PATCH 5/6] Remove Blank line --- .../Services/Instruction/IInstructionService.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Francesco.Recipes.World/Services/Instruction/IInstructionService.cs b/Francesco.Recipes.World/Services/Instruction/IInstructionService.cs index 8ddedf5..fa514a1 100644 --- a/Francesco.Recipes.World/Services/Instruction/IInstructionService.cs +++ b/Francesco.Recipes.World/Services/Instruction/IInstructionService.cs @@ -5,6 +5,5 @@ Task MoveInstructionUpAsync(Guid instructionId); Task MoveInstructionDownAsync(Guid instructionId); - } } From 71ac7eb03fb94eda51a42b593bab3bca21383a7f Mon Sep 17 00:00:00 2001 From: franc Date: Thu, 17 Apr 2025 10:34:12 +0200 Subject: [PATCH 6/6] Rename Refactoring --- .../Repositories/Instruction/IInstructionRepository.cs | 4 ++-- .../Repositories/Instruction/InstructionRepository.cs | 4 ++-- .../Services/Instruction/InstructionService.cs | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Francesco.Recipes.World/Repositories/Instruction/IInstructionRepository.cs b/Francesco.Recipes.World/Repositories/Instruction/IInstructionRepository.cs index 057eb02..e1fd1e6 100644 --- a/Francesco.Recipes.World/Repositories/Instruction/IInstructionRepository.cs +++ b/Francesco.Recipes.World/Repositories/Instruction/IInstructionRepository.cs @@ -10,8 +10,8 @@ Task RemoveInstructionFromRecipeAsync(Guid recipeId, Guid instructionId); - Task SwapInstructionOrderAsync(Instruction a, Instruction b); + Task SwapInstructionNumbersAsync(Instruction a, Instruction b); - Task> GetInstructionsByInstructionIdAsync(Guid instructionId); + Task> GetInstructionsOfRecipeAsync(Guid instructionId); } } diff --git a/Francesco.Recipes.World/Repositories/Instruction/InstructionRepository.cs b/Francesco.Recipes.World/Repositories/Instruction/InstructionRepository.cs index a95e22d..9a4445d 100644 --- a/Francesco.Recipes.World/Repositories/Instruction/InstructionRepository.cs +++ b/Francesco.Recipes.World/Repositories/Instruction/InstructionRepository.cs @@ -70,7 +70,7 @@ } } - public async Task> GetInstructionsByInstructionIdAsync(Guid instructionId) + public async Task> GetInstructionsOfRecipeAsync(Guid instructionId) { var instruction = await _context.Instructions .Include(i => i.Recipe) @@ -85,7 +85,7 @@ return instruction.Recipe.Instructions.ToList(); } - public async Task SwapInstructionOrderAsync(Instruction a, Instruction b) + public async Task SwapInstructionNumbersAsync(Instruction a, Instruction b) { if (a == null) { diff --git a/Francesco.Recipes.World/Services/Instruction/InstructionService.cs b/Francesco.Recipes.World/Services/Instruction/InstructionService.cs index 895cf66..c7a4acc 100644 --- a/Francesco.Recipes.World/Services/Instruction/InstructionService.cs +++ b/Francesco.Recipes.World/Services/Instruction/InstructionService.cs @@ -19,7 +19,7 @@ namespace Francesco.Recipes.World.Services.Instruction private async Task MoveInstructionAsync(Guid instructionId, bool moveUp) { - var instructions = await _instructionRepository.GetInstructionsByInstructionIdAsync(instructionId); + var instructions = await _instructionRepository.GetInstructionsOfRecipeAsync(instructionId); var instruction = instructions.FirstOrDefault(i => i.Id == instructionId); @@ -36,12 +36,12 @@ namespace Francesco.Recipes.World.Services.Instruction return; } - var targetNumber = moveUp ? instruction.Number - 1 : instruction.Number + 1; + var targetNumber = moveUp ? instruction.Number + 1 : instruction.Number - 1; var neighbor = instructions.FirstOrDefault(i => i.Number == targetNumber); if (neighbor != null) { - await _instructionRepository.SwapInstructionOrderAsync(instruction, neighbor); + await _instructionRepository.SwapInstructionNumbersAsync(instruction, neighbor); } } }