diff --git a/SchengenVisaApi/ApplicationLayer/CreateVisaApplicationRequest.cs b/SchengenVisaApi/ApplicationLayer/CreateVisaApplicationRequest.cs index 80ce2b0..9885310 100644 --- a/SchengenVisaApi/ApplicationLayer/CreateVisaApplicationRequest.cs +++ b/SchengenVisaApi/ApplicationLayer/CreateVisaApplicationRequest.cs @@ -3,6 +3,7 @@ using Domains.VisaApplicationDomain; namespace ApplicationLayer; +/// Model of visa request from user public record CreateVisaApplicationRequest( Name FullName, Passport Passport, diff --git a/SchengenVisaApi/Domains/VisaApplicationDomain/VisaApplication.cs b/SchengenVisaApi/Domains/VisaApplicationDomain/VisaApplication.cs index 1108852..3a51796 100644 --- a/SchengenVisaApi/Domains/VisaApplicationDomain/VisaApplication.cs +++ b/SchengenVisaApi/Domains/VisaApplicationDomain/VisaApplication.cs @@ -1,5 +1,4 @@ -using System.ComponentModel.DataAnnotations.Schema; -using Domains.ApplicantDomain; +using Domains.ApplicantDomain; using Domains.LocationDomain; namespace Domains.VisaApplicationDomain @@ -14,7 +13,7 @@ namespace Domains.VisaApplicationDomain public Guid ApplicantId { get; set; } /// Applicant of - public Applicant Applicant { get; set; } + public Applicant Applicant { get; set; } = null!; /// /// always null if is not a non-resident diff --git a/SchengenVisaApi/Infrastructure/Database/Applicants/Repositories/ApplicantsRepository.cs b/SchengenVisaApi/Infrastructure/Database/Applicants/Repositories/ApplicantsRepository.cs index a1e5170..473a43b 100644 --- a/SchengenVisaApi/Infrastructure/Database/Applicants/Repositories/ApplicantsRepository.cs +++ b/SchengenVisaApi/Infrastructure/Database/Applicants/Repositories/ApplicantsRepository.cs @@ -4,12 +4,16 @@ using Microsoft.EntityFrameworkCore; namespace Infrastructure.Database.Applicants.Repositories { - public class ApplicantsRepository(IGenericReader reader, IGenericWriter writer, IUnitOfWork unitOfWork) - : GenericRepository(writer, unitOfWork), IApplicantsRepository + /// Repository pattern for + /// + /// + /// + public sealed class ApplicantsRepository(IGenericReader reader, IGenericWriter writer, IUnitOfWork unitOfWork) + : GenericRepository(reader, writer, unitOfWork), IApplicantsRepository { protected override IQueryable LoadDomain() { - return reader.GetAll() + return base.LoadDomain() .Include(a => a.CountryOfBirth) .Include(a => a.CityOfBirth) .Include(a => a.PlaceOfWork); diff --git a/SchengenVisaApi/Infrastructure/Database/Applicants/Repositories/IApplicantsRepository.cs b/SchengenVisaApi/Infrastructure/Database/Applicants/Repositories/IApplicantsRepository.cs index fe1280c..d26b29a 100644 --- a/SchengenVisaApi/Infrastructure/Database/Applicants/Repositories/IApplicantsRepository.cs +++ b/SchengenVisaApi/Infrastructure/Database/Applicants/Repositories/IApplicantsRepository.cs @@ -3,5 +3,6 @@ using Infrastructure.Database.Generic; namespace Infrastructure.Database.Applicants.Repositories { + /// Repository pattern for public interface IApplicantsRepository : IGenericRepository { } } diff --git a/SchengenVisaApi/Infrastructure/Database/GeneralExceptions/EntityNotFoundException.cs b/SchengenVisaApi/Infrastructure/Database/GeneralExceptions/EntityNotFoundException.cs index 79e5a5a..d98221d 100644 --- a/SchengenVisaApi/Infrastructure/Database/GeneralExceptions/EntityNotFoundException.cs +++ b/SchengenVisaApi/Infrastructure/Database/GeneralExceptions/EntityNotFoundException.cs @@ -1,4 +1,10 @@ -namespace Infrastructure.Database.GeneralExceptions +using Domains; + +namespace Infrastructure.Database.GeneralExceptions { - public class EntityNotFoundException(Guid id) : Exception($"Entity {typeof(T).Name} with id '{id}' not found"); + /// Exception to throw when entity with specific id not found + /// Identifier of entity + /// Not found entity type + public class EntityNotFoundException(Guid id) : Exception($"Entity {typeof(T).Name} with id '{id}' not found") + where T : class, IEntity; } diff --git a/SchengenVisaApi/Infrastructure/Database/Generic/GenericRepository.cs b/SchengenVisaApi/Infrastructure/Database/Generic/GenericRepository.cs index 306dbde..c8c2391 100644 --- a/SchengenVisaApi/Infrastructure/Database/Generic/GenericRepository.cs +++ b/SchengenVisaApi/Infrastructure/Database/Generic/GenericRepository.cs @@ -4,35 +4,50 @@ using Microsoft.EntityFrameworkCore; namespace Infrastructure.Database.Generic { - public abstract class GenericRepository(IGenericWriter writer, IUnitOfWork unitOfWork) : IGenericRepository + /// Generic repository pattern + /// + /// + /// Type of entity + /// Should be inherited to create typed repositories + public abstract class GenericRepository(IGenericReader reader, IGenericWriter writer, IUnitOfWork unitOfWork) : IGenericRepository where T : class, IEntity { + /// public async Task> GetAllAsync(CancellationToken cancellationToken) => await LoadDomain().ToListAsync(cancellationToken); + /// public async Task GetOneAsync(Guid id, CancellationToken cancellationToken) { var result = await LoadDomain().SingleOrDefaultAsync(a => a.Id == id, cancellationToken); return result ?? throw new EntityNotFoundException(id); } + /// public async Task AddAsync(T entity, CancellationToken cancellationToken) => await writer.AddAsync(entity, cancellationToken); + /// public async Task UpdateAsync(T entity, CancellationToken cancellationToken) { await GetOneAsync(entity.Id, cancellationToken); writer.Update(entity); } + /// public void Remove(T entity) { writer.Remove(entity); } + /// public async Task SaveAsync(CancellationToken cancellationToken) => await unitOfWork.SaveAsync(cancellationToken); - protected abstract IQueryable LoadDomain(); + /// Should be overriden to load navigation properties of entity + protected virtual IQueryable LoadDomain() + { + return reader.GetAll(); + } } } diff --git a/SchengenVisaApi/Infrastructure/Database/Generic/IGenericReader.cs b/SchengenVisaApi/Infrastructure/Database/Generic/IGenericReader.cs index ecdc94a..679f42c 100644 --- a/SchengenVisaApi/Infrastructure/Database/Generic/IGenericReader.cs +++ b/SchengenVisaApi/Infrastructure/Database/Generic/IGenericReader.cs @@ -2,9 +2,10 @@ namespace Infrastructure.Database.Generic { + /// Reads from data storage public interface IGenericReader { - /// Get all entities of type stored in storage + /// Get all entities of type T stored in storage /// Entity type to seek in storage IQueryable GetAll() where T : class, IEntity; } diff --git a/SchengenVisaApi/Infrastructure/Database/Generic/IGenericRepository.cs b/SchengenVisaApi/Infrastructure/Database/Generic/IGenericRepository.cs index e7ec271..5478600 100644 --- a/SchengenVisaApi/Infrastructure/Database/Generic/IGenericRepository.cs +++ b/SchengenVisaApi/Infrastructure/Database/Generic/IGenericRepository.cs @@ -2,18 +2,36 @@ namespace Infrastructure.Database.Generic { + /// + /// Generic repository pattern + /// + /// Entity type public interface IGenericRepository where T : class, IEntity { + /// Get all entities from data storage Task> GetAllAsync(CancellationToken cancellationToken); + /// Get one entity with specific id + /// Identifier of entity Task GetOneAsync(Guid id, CancellationToken cancellationToken); + /// Add entity to storage + /// Entity to add Task AddAsync(T entity, CancellationToken cancellationToken); + /// + /// Update entity in storage + /// + /// Entity to update Task UpdateAsync(T entity, CancellationToken cancellationToken); + /// + /// Remove entity from storage + /// + /// Entity to remove void Remove(T entity); + /// Save changes in storage Task SaveAsync(CancellationToken cancellationToken); } } diff --git a/SchengenVisaApi/Infrastructure/Database/Generic/IGenericWriter.cs b/SchengenVisaApi/Infrastructure/Database/Generic/IGenericWriter.cs index c53fefe..ab2b075 100644 --- a/SchengenVisaApi/Infrastructure/Database/Generic/IGenericWriter.cs +++ b/SchengenVisaApi/Infrastructure/Database/Generic/IGenericWriter.cs @@ -6,18 +6,18 @@ namespace Infrastructure.Database.Generic /// should be used to save changes public interface IGenericWriter { - /// Add to data storage + /// Add entity to data storage /// Entity to add /// Cancellation Token /// Entity type Task AddAsync(T entity, CancellationToken cancellationToken) where T : class, IEntity; - /// Update in data storage + /// Update entity in data storage /// Entity to update /// Entity type void Update(T entity) where T : class, IEntity; - /// Remove from data storage + /// Remove entity from data storage /// Entity to remove /// Entity type void Remove(T entity) where T : class, IEntity; diff --git a/SchengenVisaApi/Infrastructure/Database/IUnitOfWork.cs b/SchengenVisaApi/Infrastructure/Database/IUnitOfWork.cs index 2b068e8..653ddbc 100644 --- a/SchengenVisaApi/Infrastructure/Database/IUnitOfWork.cs +++ b/SchengenVisaApi/Infrastructure/Database/IUnitOfWork.cs @@ -2,7 +2,7 @@ { public interface IUnitOfWork { - /// Save changes in data storage + /// Saves changes in data storage /// Cancellation Token Task SaveAsync(CancellationToken cancellationToken); } diff --git a/SchengenVisaApi/Infrastructure/Database/Locations/Repositories/Cities/CitiesRepository.cs b/SchengenVisaApi/Infrastructure/Database/Locations/Repositories/Cities/CitiesRepository.cs index da38369..b417188 100644 --- a/SchengenVisaApi/Infrastructure/Database/Locations/Repositories/Cities/CitiesRepository.cs +++ b/SchengenVisaApi/Infrastructure/Database/Locations/Repositories/Cities/CitiesRepository.cs @@ -4,12 +4,12 @@ using Microsoft.EntityFrameworkCore; namespace Infrastructure.Database.Locations.Repositories.Cities { - public class CitiesRepository(IGenericReader reader, IGenericWriter writer, IUnitOfWork unitOfWork) - : GenericRepository(writer, unitOfWork), ICitiesRepository + public sealed class CitiesRepository(IGenericReader reader, IGenericWriter writer, IUnitOfWork unitOfWork) + : GenericRepository(reader, writer, unitOfWork), ICitiesRepository { protected override IQueryable LoadDomain() { - return reader.GetAll().Include(c => c.Country); + return base.LoadDomain().Include(c => c.Country); } } } diff --git a/SchengenVisaApi/Infrastructure/Database/Locations/Repositories/Countries/CountriesRepository.cs b/SchengenVisaApi/Infrastructure/Database/Locations/Repositories/Countries/CountriesRepository.cs index f1ab02a..8d431b9 100644 --- a/SchengenVisaApi/Infrastructure/Database/Locations/Repositories/Countries/CountriesRepository.cs +++ b/SchengenVisaApi/Infrastructure/Database/Locations/Repositories/Countries/CountriesRepository.cs @@ -4,12 +4,12 @@ using Microsoft.EntityFrameworkCore; namespace Infrastructure.Database.Locations.Repositories.Countries { - public class CountriesRepository(IGenericReader reader, IGenericWriter writer, IUnitOfWork unitOfWork) - : GenericRepository(writer, unitOfWork), ICountriesRepository + public sealed class CountriesRepository(IGenericReader reader, IGenericWriter writer, IUnitOfWork unitOfWork) + : GenericRepository(reader, writer, unitOfWork), ICountriesRepository { protected override IQueryable LoadDomain() { - return reader.GetAll().Include(c => c.Cities); + return base.LoadDomain().Include(c => c.Cities); } } } diff --git a/SchengenVisaApi/Infrastructure/Database/VisaApplications/Repositories/VisaApplicationsRepository.cs b/SchengenVisaApi/Infrastructure/Database/VisaApplications/Repositories/VisaApplicationsRepository.cs index abbe608..d18d1f4 100644 --- a/SchengenVisaApi/Infrastructure/Database/VisaApplications/Repositories/VisaApplicationsRepository.cs +++ b/SchengenVisaApi/Infrastructure/Database/VisaApplications/Repositories/VisaApplicationsRepository.cs @@ -4,12 +4,12 @@ using Microsoft.EntityFrameworkCore; namespace Infrastructure.Database.VisaApplications.Repositories { - public class VisaApplicationsRepository(IGenericReader reader, IGenericWriter writer, IUnitOfWork unitOfWork) - : GenericRepository(writer, unitOfWork), IVisaApplicationsRepository + public sealed class VisaApplicationsRepository(IGenericReader reader, IGenericWriter writer, IUnitOfWork unitOfWork) + : GenericRepository(reader, writer, unitOfWork), IVisaApplicationsRepository { protected override IQueryable LoadDomain() { - return reader.GetAll() + return base.LoadDomain() .Include(a => a.DestinationCountry) .Include(a => a.PastVisas) .Include(a => a.PastVisits); diff --git a/SchengenVisaApi/Infrastructure/DependencyInjection.cs b/SchengenVisaApi/Infrastructure/DependencyInjection.cs index 7b1ef0f..156abe4 100644 --- a/SchengenVisaApi/Infrastructure/DependencyInjection.cs +++ b/SchengenVisaApi/Infrastructure/DependencyInjection.cs @@ -10,8 +10,10 @@ using DbContext = Infrastructure.Database.DbContext; namespace Infrastructure { + /// Provides methods to add services to DI-container public static class DependencyInjection { + /// Add services needed for Infrastructure layer public static IServiceCollection AddInfrastructure(this IServiceCollection services) { //TODO строка подключения