Added comments, changed generic repository, removed warnings
This commit is contained in:
		| @@ -3,6 +3,7 @@ using Domains.VisaApplicationDomain; | |||||||
|  |  | ||||||
| namespace ApplicationLayer; | namespace ApplicationLayer; | ||||||
|  |  | ||||||
|  | /// Model of visa request from user | ||||||
| public record CreateVisaApplicationRequest( | public record CreateVisaApplicationRequest( | ||||||
|     Name FullName, |     Name FullName, | ||||||
|     Passport Passport, |     Passport Passport, | ||||||
|   | |||||||
| @@ -1,5 +1,4 @@ | |||||||
| using System.ComponentModel.DataAnnotations.Schema; | using Domains.ApplicantDomain; | ||||||
| using Domains.ApplicantDomain; |  | ||||||
| using Domains.LocationDomain; | using Domains.LocationDomain; | ||||||
|  |  | ||||||
| namespace Domains.VisaApplicationDomain | namespace Domains.VisaApplicationDomain | ||||||
| @@ -14,7 +13,7 @@ namespace Domains.VisaApplicationDomain | |||||||
|         public Guid ApplicantId { get; set; } |         public Guid ApplicantId { get; set; } | ||||||
|  |  | ||||||
|         /// Applicant of <see cref="VisaApplication"/> |         /// Applicant of <see cref="VisaApplication"/> | ||||||
|         public Applicant Applicant { get; set; } |         public Applicant Applicant { get; set; } = null!; | ||||||
|  |  | ||||||
|         /// <inheritdoc cref="Domains.VisaApplicationDomain.ReentryPermit"/> |         /// <inheritdoc cref="Domains.VisaApplicationDomain.ReentryPermit"/> | ||||||
|         /// <remarks>always null if <see cref="Applicant"/> is not a non-resident</remarks> |         /// <remarks>always null if <see cref="Applicant"/> is not a non-resident</remarks> | ||||||
|   | |||||||
| @@ -4,12 +4,16 @@ using Microsoft.EntityFrameworkCore; | |||||||
|  |  | ||||||
| namespace Infrastructure.Database.Applicants.Repositories | namespace Infrastructure.Database.Applicants.Repositories | ||||||
| { | { | ||||||
|     public class ApplicantsRepository(IGenericReader reader, IGenericWriter writer, IUnitOfWork unitOfWork) |     /// Repository pattern for <see cref="Applicant"/> | ||||||
|         : GenericRepository<Applicant>(writer, unitOfWork), IApplicantsRepository |     /// <param name="reader"><inheritdoc cref="IGenericReader"/></param> | ||||||
|  |     /// <param name="writer"><inheritdoc cref="IGenericWriter"/></param> | ||||||
|  |     /// <param name="unitOfWork"><inheritdoc cref="IUnitOfWork"/></param> | ||||||
|  |     public sealed class ApplicantsRepository(IGenericReader reader, IGenericWriter writer, IUnitOfWork unitOfWork) | ||||||
|  |         : GenericRepository<Applicant>(reader, writer, unitOfWork), IApplicantsRepository | ||||||
|     { |     { | ||||||
|         protected override IQueryable<Applicant> LoadDomain() |         protected override IQueryable<Applicant> LoadDomain() | ||||||
|         { |         { | ||||||
|             return reader.GetAll<Applicant>() |             return base.LoadDomain() | ||||||
|                 .Include(a => a.CountryOfBirth) |                 .Include(a => a.CountryOfBirth) | ||||||
|                 .Include(a => a.CityOfBirth) |                 .Include(a => a.CityOfBirth) | ||||||
|                 .Include(a => a.PlaceOfWork); |                 .Include(a => a.PlaceOfWork); | ||||||
|   | |||||||
| @@ -3,5 +3,6 @@ using Infrastructure.Database.Generic; | |||||||
|  |  | ||||||
| namespace Infrastructure.Database.Applicants.Repositories | namespace Infrastructure.Database.Applicants.Repositories | ||||||
| { | { | ||||||
|  |     /// Repository pattern for <see cref="Applicant"/> | ||||||
|     public interface IApplicantsRepository : IGenericRepository<Applicant> { } |     public interface IApplicantsRepository : IGenericRepository<Applicant> { } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,4 +1,10 @@ | |||||||
| namespace Infrastructure.Database.GeneralExceptions | using Domains; | ||||||
|  |  | ||||||
|  | namespace Infrastructure.Database.GeneralExceptions | ||||||
| { | { | ||||||
|     public class EntityNotFoundException<T>(Guid id) : Exception($"Entity {typeof(T).Name} with id '{id}' not found"); |     /// Exception to throw when entity with specific id not found | ||||||
|  |     /// <param name="id">Identifier of entity</param> | ||||||
|  |     /// <typeparam name="T">Not found entity type</typeparam> | ||||||
|  |     public class EntityNotFoundException<T>(Guid id) : Exception($"Entity {typeof(T).Name} with id '{id}' not found") | ||||||
|  |         where T : class, IEntity; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -4,35 +4,50 @@ using Microsoft.EntityFrameworkCore; | |||||||
|  |  | ||||||
| namespace Infrastructure.Database.Generic | namespace Infrastructure.Database.Generic | ||||||
| { | { | ||||||
|     public abstract class GenericRepository<T>(IGenericWriter writer, IUnitOfWork unitOfWork) : IGenericRepository<T> |     /// Generic repository pattern | ||||||
|  |     /// <param name="writer"><inheritdoc cref="IGenericWriter"/></param> | ||||||
|  |     /// <param name="unitOfWork"><inheritdoc cref="IUnitOfWork"/></param> | ||||||
|  |     /// <typeparam name="T">Type of entity</typeparam> | ||||||
|  |     /// <remarks>Should be inherited to create typed repositories</remarks> | ||||||
|  |     public abstract class GenericRepository<T>(IGenericReader reader, IGenericWriter writer, IUnitOfWork unitOfWork) : IGenericRepository<T> | ||||||
|         where T : class, IEntity |         where T : class, IEntity | ||||||
|     { |     { | ||||||
|  |         /// <inheritdoc cref="IGenericRepository{T}.GetAllAsync"/> | ||||||
|         public async Task<List<T>> GetAllAsync(CancellationToken cancellationToken) |         public async Task<List<T>> GetAllAsync(CancellationToken cancellationToken) | ||||||
|             => await LoadDomain().ToListAsync(cancellationToken); |             => await LoadDomain().ToListAsync(cancellationToken); | ||||||
|  |  | ||||||
|  |         /// <inheritdoc cref="IGenericRepository{T}.GetOneAsync"/> | ||||||
|         public async Task<T> GetOneAsync(Guid id, CancellationToken cancellationToken) |         public async Task<T> GetOneAsync(Guid id, CancellationToken cancellationToken) | ||||||
|         { |         { | ||||||
|             var result = await LoadDomain().SingleOrDefaultAsync(a => a.Id == id, cancellationToken); |             var result = await LoadDomain().SingleOrDefaultAsync(a => a.Id == id, cancellationToken); | ||||||
|             return result ?? throw new EntityNotFoundException<T>(id); |             return result ?? throw new EntityNotFoundException<T>(id); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         /// <inheritdoc cref="IGenericRepository{T}.AddAsync"/> | ||||||
|         public async Task AddAsync(T entity, CancellationToken cancellationToken) |         public async Task AddAsync(T entity, CancellationToken cancellationToken) | ||||||
|             => await writer.AddAsync(entity, cancellationToken); |             => await writer.AddAsync(entity, cancellationToken); | ||||||
|  |  | ||||||
|  |         /// <inheritdoc cref="IGenericRepository{T}.UpdateAsync"/> | ||||||
|         public async Task UpdateAsync(T entity, CancellationToken cancellationToken) |         public async Task UpdateAsync(T entity, CancellationToken cancellationToken) | ||||||
|         { |         { | ||||||
|             await GetOneAsync(entity.Id, cancellationToken); |             await GetOneAsync(entity.Id, cancellationToken); | ||||||
|             writer.Update(entity); |             writer.Update(entity); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         /// <inheritdoc cref="IGenericRepository{T}.Remove"/> | ||||||
|         public void Remove(T entity) |         public void Remove(T entity) | ||||||
|         { |         { | ||||||
|             writer.Remove(entity); |             writer.Remove(entity); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         /// <inheritdoc cref="IGenericRepository{T}.SaveAsync"/> | ||||||
|         public async Task SaveAsync(CancellationToken cancellationToken) |         public async Task SaveAsync(CancellationToken cancellationToken) | ||||||
|             => await unitOfWork.SaveAsync(cancellationToken); |             => await unitOfWork.SaveAsync(cancellationToken); | ||||||
|  |  | ||||||
|         protected abstract IQueryable<T> LoadDomain(); |         /// Should be overriden to load navigation properties of entity | ||||||
|  |         protected virtual IQueryable<T> LoadDomain() | ||||||
|  |         { | ||||||
|  |             return reader.GetAll<T>(); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -2,9 +2,10 @@ | |||||||
|  |  | ||||||
| namespace Infrastructure.Database.Generic | namespace Infrastructure.Database.Generic | ||||||
| { | { | ||||||
|  |     /// Reads from data storage | ||||||
|     public interface IGenericReader |     public interface IGenericReader | ||||||
|     { |     { | ||||||
|         /// Get all entities of type <typeparamref name="T"/> stored in storage |         /// Get all entities of type T stored in storage | ||||||
|         /// <typeparam name="T">Entity type to seek in storage</typeparam> |         /// <typeparam name="T">Entity type to seek in storage</typeparam> | ||||||
|         IQueryable<T> GetAll<T>() where T : class, IEntity; |         IQueryable<T> GetAll<T>() where T : class, IEntity; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -2,18 +2,36 @@ | |||||||
|  |  | ||||||
| namespace Infrastructure.Database.Generic | namespace Infrastructure.Database.Generic | ||||||
| { | { | ||||||
|  |     /// <summary> | ||||||
|  |     /// Generic repository pattern | ||||||
|  |     /// </summary> | ||||||
|  |     /// <typeparam name="T">Entity type</typeparam> | ||||||
|     public interface IGenericRepository<T> where T : class, IEntity |     public interface IGenericRepository<T> where T : class, IEntity | ||||||
|     { |     { | ||||||
|  |         /// Get all entities from data storage | ||||||
|         Task<List<T>> GetAllAsync(CancellationToken cancellationToken); |         Task<List<T>> GetAllAsync(CancellationToken cancellationToken); | ||||||
|  |  | ||||||
|  |         /// Get one entity with specific id | ||||||
|  |         /// <param name="id">Identifier of entity</param> | ||||||
|         Task<T> GetOneAsync(Guid id, CancellationToken cancellationToken); |         Task<T> GetOneAsync(Guid id, CancellationToken cancellationToken); | ||||||
|  |  | ||||||
|  |         /// Add entity to storage | ||||||
|  |         /// <param name="entity">Entity to add</param> | ||||||
|         Task AddAsync(T entity, CancellationToken cancellationToken); |         Task AddAsync(T entity, CancellationToken cancellationToken); | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Update entity in storage | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="entity">Entity to update</param> | ||||||
|         Task UpdateAsync(T entity, CancellationToken cancellationToken); |         Task UpdateAsync(T entity, CancellationToken cancellationToken); | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Remove entity from storage | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="entity">Entity to remove</param> | ||||||
|         void Remove(T entity); |         void Remove(T entity); | ||||||
|  |  | ||||||
|  |         /// Save changes in storage | ||||||
|         Task SaveAsync(CancellationToken cancellationToken); |         Task SaveAsync(CancellationToken cancellationToken); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -6,18 +6,18 @@ namespace Infrastructure.Database.Generic | |||||||
|     /// <remarks><see cref="IUnitOfWork"/> should be used to save changes</remarks> |     /// <remarks><see cref="IUnitOfWork"/> should be used to save changes</remarks> | ||||||
|     public interface IGenericWriter |     public interface IGenericWriter | ||||||
|     { |     { | ||||||
|         /// Add <paramref name="entity"/> to data storage |         /// Add entity to data storage | ||||||
|         /// <param name="entity">Entity to add</param> |         /// <param name="entity">Entity to add</param> | ||||||
|         /// <param name="cancellationToken">Cancellation Token</param> |         /// <param name="cancellationToken">Cancellation Token</param> | ||||||
|         /// <typeparam name="T">Entity type</typeparam> |         /// <typeparam name="T">Entity type</typeparam> | ||||||
|         Task AddAsync<T>(T entity, CancellationToken cancellationToken) where T : class, IEntity; |         Task AddAsync<T>(T entity, CancellationToken cancellationToken) where T : class, IEntity; | ||||||
|  |  | ||||||
|         /// Update <paramref name="entity"/> in data storage |         /// Update entity in data storage | ||||||
|         /// <param name="entity">Entity to update</param> |         /// <param name="entity">Entity to update</param> | ||||||
|         /// <typeparam name="T">Entity type</typeparam> |         /// <typeparam name="T">Entity type</typeparam> | ||||||
|         void Update<T>(T entity) where T : class, IEntity; |         void Update<T>(T entity) where T : class, IEntity; | ||||||
|  |  | ||||||
|         /// Remove <paramref name="entity"/> from data storage |         /// Remove entity from data storage | ||||||
|         /// <param name="entity">Entity to remove</param> |         /// <param name="entity">Entity to remove</param> | ||||||
|         /// <typeparam name="T">Entity type</typeparam> |         /// <typeparam name="T">Entity type</typeparam> | ||||||
|         void Remove<T>(T entity) where T : class, IEntity; |         void Remove<T>(T entity) where T : class, IEntity; | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ | |||||||
| { | { | ||||||
|     public interface IUnitOfWork |     public interface IUnitOfWork | ||||||
|     { |     { | ||||||
|         /// Save changes in data storage |         /// Saves changes in data storage | ||||||
|         /// <param name="cancellationToken">Cancellation Token</param> |         /// <param name="cancellationToken">Cancellation Token</param> | ||||||
|         Task SaveAsync(CancellationToken cancellationToken); |         Task SaveAsync(CancellationToken cancellationToken); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -4,12 +4,12 @@ using Microsoft.EntityFrameworkCore; | |||||||
|  |  | ||||||
| namespace Infrastructure.Database.Locations.Repositories.Cities | namespace Infrastructure.Database.Locations.Repositories.Cities | ||||||
| { | { | ||||||
|     public class CitiesRepository(IGenericReader reader, IGenericWriter writer, IUnitOfWork unitOfWork) |     public sealed class CitiesRepository(IGenericReader reader, IGenericWriter writer, IUnitOfWork unitOfWork) | ||||||
|         : GenericRepository<City>(writer, unitOfWork), ICitiesRepository |         : GenericRepository<City>(reader, writer, unitOfWork), ICitiesRepository | ||||||
|     { |     { | ||||||
|         protected override IQueryable<City> LoadDomain() |         protected override IQueryable<City> LoadDomain() | ||||||
|         { |         { | ||||||
|             return reader.GetAll<City>().Include(c => c.Country); |             return base.LoadDomain().Include(c => c.Country); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -4,12 +4,12 @@ using Microsoft.EntityFrameworkCore; | |||||||
|  |  | ||||||
| namespace Infrastructure.Database.Locations.Repositories.Countries | namespace Infrastructure.Database.Locations.Repositories.Countries | ||||||
| { | { | ||||||
|     public class CountriesRepository(IGenericReader reader, IGenericWriter writer, IUnitOfWork unitOfWork) |     public sealed class CountriesRepository(IGenericReader reader, IGenericWriter writer, IUnitOfWork unitOfWork) | ||||||
|         : GenericRepository<Country>(writer, unitOfWork), ICountriesRepository |         : GenericRepository<Country>(reader, writer, unitOfWork), ICountriesRepository | ||||||
|     { |     { | ||||||
|         protected override IQueryable<Country> LoadDomain() |         protected override IQueryable<Country> LoadDomain() | ||||||
|         { |         { | ||||||
|             return reader.GetAll<Country>().Include(c => c.Cities); |             return base.LoadDomain().Include(c => c.Cities); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -4,12 +4,12 @@ using Microsoft.EntityFrameworkCore; | |||||||
|  |  | ||||||
| namespace Infrastructure.Database.VisaApplications.Repositories | namespace Infrastructure.Database.VisaApplications.Repositories | ||||||
| { | { | ||||||
|     public class VisaApplicationsRepository(IGenericReader reader, IGenericWriter writer, IUnitOfWork unitOfWork) |     public sealed class VisaApplicationsRepository(IGenericReader reader, IGenericWriter writer, IUnitOfWork unitOfWork) | ||||||
|         : GenericRepository<VisaApplication>(writer, unitOfWork), IVisaApplicationsRepository |         : GenericRepository<VisaApplication>(reader, writer, unitOfWork), IVisaApplicationsRepository | ||||||
|     { |     { | ||||||
|         protected override IQueryable<VisaApplication> LoadDomain() |         protected override IQueryable<VisaApplication> LoadDomain() | ||||||
|         { |         { | ||||||
|             return reader.GetAll<VisaApplication>() |             return base.LoadDomain() | ||||||
|                 .Include(a => a.DestinationCountry) |                 .Include(a => a.DestinationCountry) | ||||||
|                 .Include(a => a.PastVisas) |                 .Include(a => a.PastVisas) | ||||||
|                 .Include(a => a.PastVisits); |                 .Include(a => a.PastVisits); | ||||||
|   | |||||||
| @@ -10,8 +10,10 @@ using DbContext = Infrastructure.Database.DbContext; | |||||||
|  |  | ||||||
| namespace Infrastructure | namespace Infrastructure | ||||||
| { | { | ||||||
|  |     /// Provides methods to add services to DI-container | ||||||
|     public static class DependencyInjection |     public static class DependencyInjection | ||||||
|     { |     { | ||||||
|  |         /// Add services needed for Infrastructure layer | ||||||
|         public static IServiceCollection AddInfrastructure(this IServiceCollection services) |         public static IServiceCollection AddInfrastructure(this IServiceCollection services) | ||||||
|         { |         { | ||||||
|             //TODO строка подключения |             //TODO строка подключения | ||||||
|   | |||||||
| @@ -16,6 +16,7 @@ namespace SchengenVisaApi | |||||||
|             return services; |             return services; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         /// Add services needed for Presentation layer | ||||||
|         private static IServiceCollection AddPresentation(this IServiceCollection services) |         private static IServiceCollection AddPresentation(this IServiceCollection services) | ||||||
|         { |         { | ||||||
|             services.AddControllers(); |             services.AddControllers(); | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ | |||||||
|     /// Provides methods for configuring middleware |     /// Provides methods for configuring middleware | ||||||
|     public static class PipelineRequest |     public static class PipelineRequest | ||||||
|     { |     { | ||||||
|         /// Configure general middleware |         /// Configure middleware | ||||||
|         public static WebApplication ConfigurePipelineRequest(this WebApplication app) |         public static WebApplication ConfigurePipelineRequest(this WebApplication app) | ||||||
|         { |         { | ||||||
|             app.UseSwagger() |             app.UseSwagger() | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user