1
0
mirror of https://github.com/XFox111/PhonebookService.git synced 2026-04-22 06:29:55 +03:00

Implemented infrastructure layer

This commit is contained in:
Eugene Fox
2023-02-22 16:05:59 +03:00
parent 340500ebbd
commit efeff9626a
5 changed files with 166 additions and 0 deletions
@@ -0,0 +1,24 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using PhonebookService.Domain.Models;
namespace PhonebookService.Infrastructure.ModelConfigurations;
/// <summary>
/// EF entity model configuration class for <see cref="Domain.Models.PhonebookRecord"/>
/// </summary>
public class PhonebookRecordEntityTypeConfiguration
: IEntityTypeConfiguration<PhonebookRecord>
{
public void Configure(EntityTypeBuilder<PhonebookRecord> builder)
{
builder.HasKey(i => i.Id);
builder.Property(i => i.FirstName).IsRequired();
builder.Property(i => i.LastName).IsRequired();
builder.Property(i => i.Email).IsRequired();
builder.Property(i => i.PhoneNumber).IsRequired();
builder.Property(i => i.StreetAddress).IsRequired();
builder.Property(i => i.City).IsRequired();
builder.Property(i => i.ZipCode).IsRequired();
}
}
@@ -0,0 +1,24 @@
using Microsoft.EntityFrameworkCore;
using PhonebookService.Domain.Models;
using PhonebookService.Infrastructure.ModelConfigurations;
namespace PhonebookService.Infrastructure;
/// <summary>
/// Phonebook EF database context
/// </summary>
public class PhonebookContext : DbContext
{
public DbSet<PhonebookRecord> Records { get; set; }
#pragma warning disable CS8618 // Non-nullable property must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
public PhonebookContext(DbContextOptions<PhonebookContext> options) : base(options) {}
#pragma warning restore CS8618 // Non-nullable property must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
protected override void OnModelCreating(ModelBuilder builder)
{
builder.ApplyConfiguration(new PhonebookRecordEntityTypeConfiguration());
}
}
@@ -0,0 +1,35 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.EntityFrameworkCore;
using PhonebookService.Domain.Repositories;
using PhonebookService.Infrastructure.Repositories;
namespace PhonebookService.Infrastructure;
/// <summary>
/// Extension class that helps to setup infrastructure layer
/// </summary>
public static class PhonebookInfrastructureExtensions
{
/// <summary>
/// Configure infrastructure layer
/// </summary>
/// <param name="services">Collection of webapp services</param>
/// <param name="configuration">Webapp configuration entity</param>
/// <param name="enableSensitiveDataLogging">If set true, EF will not hide personal data (e.g. passwords) when logging. Use only on debug!</param>
public static IServiceCollection ConfigureInfrastructure(this IServiceCollection services, IConfiguration configuration, bool enableSensitiveDataLogging = false)
{
services.AddDbContext<PhonebookContext>(options =>
{
options.UseInMemoryDatabase("PhonebookDatabase");
// options.UseSqlServer(configuration.GetConnectionString("PhonebookDatabase"));
if (enableSensitiveDataLogging)
options.EnableSensitiveDataLogging();
});
services.AddScoped<IPhonebookRepository, PhonebookRepository>();
return services;
}
}
@@ -6,6 +6,8 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.3" /> <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.3" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />
</ItemGroup> </ItemGroup>
<PropertyGroup> <PropertyGroup>
@@ -0,0 +1,81 @@
using PhonebookService.Domain.Models;
using PhonebookService.Domain.Queries;
using PhonebookService.Domain.Repositories;
namespace PhonebookService.Infrastructure.Repositories;
/// <summary>
/// Phonebook repository implementation
/// </summary>
public class PhonebookRepository : IPhonebookRepository
{
private readonly PhonebookContext _context;
public PhonebookRepository(PhonebookContext context)
{
_context = context ?? throw new ArgumentNullException(nameof(context));
}
/// <inheritdoc/>
public async Task<PhonebookRecord> CreateItemAsync(PhonebookRecord item)
{
var entry = await _context.Records.AddAsync(item);
await _context.SaveChangesAsync();
return entry.Entity;
}
/// <inheritdoc/>
public async Task DeleteItemAsync(PhonebookRecord item)
{
_context.Records.Remove(item);
await _context.SaveChangesAsync();
}
/// <inheritdoc/>
public async Task<PhonebookRecord?> GetItemByIdAsync(int id)
{
var entry = await _context.Records.FindAsync(id);
return entry;
}
/// <inheritdoc/>
public Task<ICollection<PhonebookRecord>> GetItemsAsync(PhonebookFilterQuery query)
{
IQueryable<PhonebookRecord> dbQuery = _context.Records;
if (query.FirstName is not null)
dbQuery = dbQuery.Where(i => i.FirstName.Contains(query.FirstName));
if (query.Phone is not null)
dbQuery = dbQuery.Where(i => i.PhoneNumber == query.Phone);
if (query.City is not null)
dbQuery = dbQuery.Where(i => i.City == query.City);
if (query.ZipCode is not null)
dbQuery = dbQuery.Where(i => i.ZipCode == query.ZipCode);
if (query.Sort == SortMode.Ascending)
dbQuery = dbQuery.OrderBy(i => i.FirstName);
else if (query.Sort == SortMode.Descending)
dbQuery = dbQuery.OrderByDescending(i => i.FirstName);
ICollection<PhonebookRecord> list = dbQuery.Skip((query.Page - 1) * 5).Take(5).ToList();
return Task.FromResult(list);
}
/// <inheritdoc/>
public async Task<PhonebookRecord> UpdateItemAsync(PhonebookRecord item)
{
var entry = _context.Records.Update(item);
await _context.SaveChangesAsync();
return entry.Entity;
}
}