From 1a6a2c9ed2e21560aacc81ebb380181060116999 Mon Sep 17 00:00:00 2001 From: Mohab Sobhy Date: Sat, 14 Feb 2026 20:23:54 +0200 Subject: [PATCH] refactor: extract ProjectController data access into repository --- .../Controllers/ProjectController.cs | 47 +++--------- .../Extensions/ServiceExtensions.cs | 4 +- .../Repositories/IProjectRepository.cs | 14 ++++ .../Repositories/ProjectRepository.cs | 74 +++++++++++++++++++ 4 files changed, 102 insertions(+), 37 deletions(-) create mode 100644 src/Analysim.Web/Repositories/IProjectRepository.cs create mode 100644 src/Analysim.Web/Repositories/ProjectRepository.cs diff --git a/src/Analysim.Web/Controllers/ProjectController.cs b/src/Analysim.Web/Controllers/ProjectController.cs index fe15958..d40f643 100644 --- a/src/Analysim.Web/Controllers/ProjectController.cs +++ b/src/Analysim.Web/Controllers/ProjectController.cs @@ -1,4 +1,4 @@ -using Internal; +using Internal; using Azure.Storage.Blobs; using Azure.Storage.Blobs.Models; using Microsoft.AspNetCore.Mvc; @@ -12,6 +12,7 @@ using System.Threading.Tasks; using Infrastructure.Data; using Core.Interfaces; +using Web.Repositories; using Web.ViewModels.Project; using Core.Entities; using System.Net.Http; @@ -39,11 +40,13 @@ public class ProjectController : ControllerBase private readonly ApplicationDbContext _dbContext; private readonly IConfiguration _configuration; + private readonly IProjectRepository _projectRepository; - public ProjectController(ApplicationDbContext dbContext, IConfiguration configuration) + public ProjectController(ApplicationDbContext dbContext, IConfiguration configuration, IProjectRepository projectRepository) { _dbContext = dbContext; _configuration = configuration; + _projectRepository = projectRepository; } #region GET REQUEST @@ -58,12 +61,7 @@ public IActionResult GetProjectByID([FromRoute] int projectID) { // Find Project // Include To Many List - var project = _dbContext.Projects - .Include(p => p.BlobFiles) - .Include(p => p.ProjectUsers) - .Include(p => p.Notebooks) - .Include(p => p.ProjectTags).ThenInclude(pt => pt.Tag) - .SingleOrDefault(p => p.ProjectID == projectID); + var project = _projectRepository.GetProjectById(projectID); if (project == null) return NotFound(new { message = "Project Not Found" }); // Return Ok Request @@ -84,12 +82,7 @@ public IActionResult GetProjectByID([FromRoute] int projectID) public IActionResult GetProjectByRoute([FromRoute] string owner, [FromRoute] string projectname) { // Find Project - var project = _dbContext.Projects - .Include(p => p.BlobFiles) - .Include(p => p.Notebooks) - .Include(p => p.ProjectUsers).ThenInclude(pu => pu.User) - .Include(p => p.ProjectTags).ThenInclude(pt => pt.Tag) - .SingleOrDefault(p => p.Route.ToLower() == owner.ToLower() + "/" + projectname.ToLower()); + var project = _projectRepository.GetProjectByRoute(owner, projectname); if (project == null) return NotFound(new { message = "Project Not Found" }); // Return Ok Request @@ -109,12 +102,7 @@ public IActionResult GetProjectByRoute([FromRoute] string owner, [FromRoute] str public IActionResult GetProjectRange([FromQuery(Name = "id")] List idList) { // Find Project - var projects = _dbContext.Projects - .Include(p => p.BlobFiles) - .Include(p => p.ProjectUsers) - .Include(p => p.ProjectTags).ThenInclude(pt => pt.Tag) - .Where(p => idList.Contains(p.ProjectID)) - .ToList(); + var projects = _projectRepository.GetProjectRange(idList); // Return Ok Request return Ok(new @@ -134,11 +122,7 @@ public IActionResult GetProjectList() { // Get All Project And Include To Many List - var projects = _dbContext.Projects - .Include(p => p.BlobFiles) - .Include(p => p.ProjectUsers) - .Include(p => p.ProjectTags).ThenInclude(pt => pt.Tag) - .ToList(); + var projects = _projectRepository.GetProjectList(); // Return Ok Request return Ok(new @@ -156,17 +140,8 @@ public IActionResult GetProjectList() [HttpGet("[action]")] public IActionResult Search([FromQuery(Name = "term")] List searchTerms) { - var matchedTag = _dbContext.Tag - .ToList() - .Where(t => searchTerms.Any(st => t.Name.ToLower().Contains(st.ToLower()))); - - var matchedProject = _dbContext.Projects - .Include(p => p.BlobFiles) - .Include(p => p.ProjectUsers) - .Include(p => p.ProjectTags).ThenInclude(pt => pt.Tag) - .ToList() - .Where(p => matchedTag.Any(mt => p.ProjectTags.Any(pt => pt.Tag.Name.ToLower() == mt.Name.ToLower()))); - if (matchedProject.Count() == 0) return NoContent(); + var matchedProject = _projectRepository.Search(searchTerms); + if (matchedProject.Count == 0) return NoContent(); return Ok(new { diff --git a/src/Analysim.Web/Extensions/ServiceExtensions.cs b/src/Analysim.Web/Extensions/ServiceExtensions.cs index 7fd1cb8..4badbf2 100644 --- a/src/Analysim.Web/Extensions/ServiceExtensions.cs +++ b/src/Analysim.Web/Extensions/ServiceExtensions.cs @@ -1,9 +1,10 @@ -using Infrastructure.Data; +using Infrastructure.Data; using Core.Helper; using Core.Entities; using Core.Services; using Azure.Storage.Blobs; using Microsoft.AspNetCore.Authentication.JwtBearer; +using Web.Repositories; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; @@ -68,6 +69,7 @@ public static void ConfigureDatabase(this IServiceCollection services, IConfigur services.AddEntityFrameworkNpgsql() .AddDbContext(opt => opt.UseNpgsql(configuration.GetConnectionString("DBConnectionString"), x => x.MigrationsAssembly("Analysim.Infrastructure"))); + services.AddScoped(); } public static void ConfigureJWT(this IServiceCollection services, IConfiguration configuration) diff --git a/src/Analysim.Web/Repositories/IProjectRepository.cs b/src/Analysim.Web/Repositories/IProjectRepository.cs new file mode 100644 index 0000000..26e9280 --- /dev/null +++ b/src/Analysim.Web/Repositories/IProjectRepository.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Core.Entities; + +namespace Web.Repositories +{ + public interface IProjectRepository + { + Project GetProjectById(int projectID); + Project GetProjectByRoute(string owner, string projectname); + List GetProjectRange(List idList); + List GetProjectList(); + List Search(List searchTerms); + } +} diff --git a/src/Analysim.Web/Repositories/ProjectRepository.cs b/src/Analysim.Web/Repositories/ProjectRepository.cs new file mode 100644 index 0000000..6495cdd --- /dev/null +++ b/src/Analysim.Web/Repositories/ProjectRepository.cs @@ -0,0 +1,74 @@ +using System.Collections.Generic; +using System.Linq; +using Core.Entities; +using Infrastructure.Data; +using Microsoft.EntityFrameworkCore; + +namespace Web.Repositories +{ + public class ProjectRepository : IProjectRepository + { + private readonly ApplicationDbContext _context; + + public ProjectRepository(ApplicationDbContext context) + { + _context = context; + } + + public Project GetProjectById(int projectID) + { + return _context.Projects + .Include(p => p.BlobFiles) + .Include(p => p.ProjectUsers) + .Include(p => p.Notebooks) + .Include(p => p.ProjectTags).ThenInclude(pt => pt.Tag) + .SingleOrDefault(p => p.ProjectID == projectID); + } + + public Project GetProjectByRoute(string owner, string projectname) + { + return _context.Projects + .Include(p => p.BlobFiles) + .Include(p => p.Notebooks) + .Include(p => p.ProjectUsers).ThenInclude(pu => pu.User) + .Include(p => p.ProjectTags).ThenInclude(pt => pt.Tag) + .SingleOrDefault(p => p.Route.ToLower() == owner.ToLower() + "/" + projectname.ToLower()); + } + + public List GetProjectRange(List idList) + { + return _context.Projects + .Include(p => p.BlobFiles) + .Include(p => p.ProjectUsers) + .Include(p => p.ProjectTags).ThenInclude(pt => pt.Tag) + .Where(p => idList.Contains(p.ProjectID)) + .ToList(); + } + + public List GetProjectList() + { + return _context.Projects + .Include(p => p.BlobFiles) + .Include(p => p.ProjectUsers) + .Include(p => p.ProjectTags).ThenInclude(pt => pt.Tag) + .ToList(); + } + + public List Search(List searchTerms) + { + var matchedTag = _context.Tag + .ToList() + .Where(t => searchTerms.Any(st => t.Name.ToLower().Contains(st.ToLower()))); + + var matchedProject = _context.Projects + .Include(p => p.BlobFiles) + .Include(p => p.ProjectUsers) + .Include(p => p.ProjectTags).ThenInclude(pt => pt.Tag) + .ToList() + .Where(p => matchedTag.Any(mt => p.ProjectTags.Any(pt => pt.Tag.Name.ToLower() == mt.Name.ToLower()))) + .ToList(); + + return matchedProject; + } + } +}