Предвариельный

This commit is contained in:
romai 2024-12-08 22:57:55 +04:00
parent fd9be0de02
commit 66560bbcd5
28 changed files with 597 additions and 10 deletions

View File

@ -3,7 +3,15 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.11.35312.102
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Domain", "Domain\Domain.csproj", "{08EF65A6-323C-4B7D-8B2E-97914E137B21}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Domain", "Domain\Domain.csproj", "{08EF65A6-323C-4B7D-8B2E-97914E137B21}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Persistence", "Persistence\Persistence.csproj", "{DDC46759-F840-4F65-BE42-18F8E7595E1F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Services.Abstractions", "Services.Abstractions\Services.Abstractions.csproj", "{8A734C61-6870-4549-9FFD-9981BCE9205C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Contracts", "Contracts\Contracts.csproj", "{973F121B-D227-46A0-9078-A0D6D6CADC56}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Services", "Services\Services.csproj", "{4CCFADCD-9E80-4B66-A6D8-B6FC5490A0C0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -15,6 +23,22 @@ Global
{08EF65A6-323C-4B7D-8B2E-97914E137B21}.Debug|Any CPU.Build.0 = Debug|Any CPU
{08EF65A6-323C-4B7D-8B2E-97914E137B21}.Release|Any CPU.ActiveCfg = Release|Any CPU
{08EF65A6-323C-4B7D-8B2E-97914E137B21}.Release|Any CPU.Build.0 = Release|Any CPU
{DDC46759-F840-4F65-BE42-18F8E7595E1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DDC46759-F840-4F65-BE42-18F8E7595E1F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DDC46759-F840-4F65-BE42-18F8E7595E1F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DDC46759-F840-4F65-BE42-18F8E7595E1F}.Release|Any CPU.Build.0 = Release|Any CPU
{8A734C61-6870-4549-9FFD-9981BCE9205C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8A734C61-6870-4549-9FFD-9981BCE9205C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8A734C61-6870-4549-9FFD-9981BCE9205C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8A734C61-6870-4549-9FFD-9981BCE9205C}.Release|Any CPU.Build.0 = Release|Any CPU
{973F121B-D227-46A0-9078-A0D6D6CADC56}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{973F121B-D227-46A0-9078-A0D6D6CADC56}.Debug|Any CPU.Build.0 = Debug|Any CPU
{973F121B-D227-46A0-9078-A0D6D6CADC56}.Release|Any CPU.ActiveCfg = Release|Any CPU
{973F121B-D227-46A0-9078-A0D6D6CADC56}.Release|Any CPU.Build.0 = Release|Any CPU
{4CCFADCD-9E80-4B66-A6D8-B6FC5490A0C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4CCFADCD-9E80-4B66-A6D8-B6FC5490A0C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4CCFADCD-9E80-4B66-A6D8-B6FC5490A0C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4CCFADCD-9E80-4B66-A6D8-B6FC5490A0C0}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -0,0 +1,8 @@
using Domain.Entities;
namespace Contracts
{
public record CityDto(Guid Id, string Name, Guid RegionId, List<StreetDto> Streets);
public record CityDtoForCreate(string Name, Guid RegionId);
public record CityDtoForUpdate(Guid Id, string Name, Guid RegionId, List<StreetDto> Streets);
}

View File

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Domain\Domain.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,8 @@
using Domain.Entities;
namespace Contracts
{
public record RegionDto(Guid Id, string Name, int Code);
public record RegionDtoForCreate(string Name, int Code);
public record RegionDtoForUpdate(string Name, int Code, List<CityDto>? Cities);
}

View File

@ -0,0 +1,9 @@
namespace Contracts
{
public record StreetDto(Guid Id, string Name, List<int> HouseNumbers,
int Index, int OkatoCode, int TaxCode, Guid CityId);
public record StreetDtoForCreate(string Name, List<int> HouseNumbers,
int Index, int OkatoCode, int TaxCode, Guid CityId);
public record StreetDtoForUpdate(string Name, List<int> HouseNumbers,
int Index, int OkatoCode, int TaxCode, Guid CityId);
}

View File

@ -1,7 +0,0 @@
namespace Domain
{
public class Class1
{
}
}

View File

@ -1,9 +1,13 @@
namespace Domain.Entities
{
public class City // города и населённые пункты *
public class City
{
public Guid Id { get; set; }
public string Name { get; set; } = string.Empty;
public Guid RegionId { get; set; }
public Region Region { get; set; } = null!;
public List<Street> Streets { get; set; } = new List<Street>();
}
}

View File

@ -5,5 +5,7 @@
public Guid Id { get; set; }
public string Name { get; set; } = string.Empty;
public int Code { get; set; }
public List<City> Cities { get; set; } = new List<City>();
}
}

View File

@ -4,9 +4,13 @@
{
public Guid Id { get; set; }
public string Name { get; set; } = string.Empty;
public List<int> HouseNumbers { get; set; }
public List<int> HouseNumbers { get; set; } = new List<int>();
public int Index { get; set; }
public int OkatoCode { get; set; }
public int TaxCode { get; set; }
public Guid CityId { get; set; }
public City City { get; set; } = null!;
}
}

View File

@ -0,0 +1,13 @@
using Domain.Entities;
namespace Domain.Repository
{
public interface ICityRepository
{
Task<City> GetByIdAsync(Guid id);
Task<List<City>> GetAllAsync();
Task AddAsync(City city);
Task UpdateAsync(City city);
Task DeleteAsync(City city);
}
}

View File

@ -0,0 +1,13 @@
using Domain.Entities;
namespace Domain.Repository
{
public interface IRegionRepository
{
Task<Region> GetByIdAsync(Guid id);
Task<List<Region>> GetAllAsync();
Task AddAsync(Region region);
Task UpdateAsync(Region region);
Task DeleteAsync(Region region);
}
}

View File

@ -0,0 +1,13 @@
using Domain.Entities;
namespace Domain.Repository
{
public interface IStreetRepository
{
Task<Street> GetByIdAsync(Guid id);
Task<List<Street>> GetAllAsync();
Task AddAsync(Street street);
Task UpdateAsync(Street street);
Task DeleteAsync(Street street);
}
}

View File

@ -0,0 +1,29 @@
using Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Persistence.Configurations
{
public class CityConfiguration : IEntityTypeConfiguration<City>
{
public void Configure(EntityTypeBuilder<City> builder)
{
builder.HasKey(c => c.Id);
builder.Property(c => c.Name)
.IsRequired()
.HasMaxLength(100);
builder.HasOne(c => c.Region)
.WithMany(r => r.Cities)
.HasForeignKey(c => c.RegionId)
.OnDelete(DeleteBehavior.Cascade); ;
builder.HasMany(c => c.Streets)
.WithOne(s => s.City)
.HasForeignKey(s => s.CityId)
.OnDelete(DeleteBehavior.Cascade); ;
}
}
}

View File

@ -0,0 +1,26 @@
using Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Persistence.Configurations
{
public class RegionConfiguration : IEntityTypeConfiguration<Region>
{
public void Configure(EntityTypeBuilder<Region> builder)
{
builder.HasKey(r => r.Id);
builder.Property(r => r.Name)
.IsRequired()
.HasMaxLength(100);
builder.Property(r => r.Code)
.IsRequired();
builder.HasMany(r => r.Cities)
.WithOne(c => c.Region)
.HasForeignKey(c => c.RegionId)
.OnDelete(DeleteBehavior.Cascade); ;
}
}
}

View File

@ -0,0 +1,34 @@
using Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.Extensions.Logging;
namespace Persistence.Configurations
{
public class StreetConfiguration : IEntityTypeConfiguration<Street>
{
public void Configure(EntityTypeBuilder<Street> builder)
{
builder.HasKey(s => s.Id);
builder.Property(s => s.Name)
.IsRequired()
.HasMaxLength(100);
builder.Property(s => s.Index)
.IsRequired();
builder.Property(s => s.OkatoCode)
.IsRequired();
builder.Property(s => s.TaxCode)
.IsRequired();
builder.HasOne(s => s.City)
.WithMany(c => c.Streets)
.HasForeignKey(s => s.CityId)
.OnDelete(DeleteBehavior.Cascade); ;
}
}
}

View File

@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Domain\Domain.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,48 @@
using Domain.Entities;
using Domain.Repository;
using Microsoft.EntityFrameworkCore;
namespace Persistence.Repositories
{
public class CityRepository : ICityRepository
{
public readonly RepositoryDbContext _dbContext;
public CityRepository(RepositoryDbContext dbContext)
{
_dbContext = dbContext;
}
public async Task AddAsync(City city)
{
await _dbContext.Cities.AddAsync(city);
await _dbContext.SaveChangesAsync();
}
public async Task DeleteAsync(City city)
{
_dbContext.Cities.Remove(city);
await _dbContext.SaveChangesAsync();
}
public async Task<List<City>> GetAllAsync()
{
return await _dbContext.Cities
.Include(c => c.Region)
.Include(c => c.Streets)
.ToListAsync();
}
public async Task<City> GetByIdAsync(Guid id)
{
return await _dbContext.Cities
.Include(c => c.Region)
.Include(c => c.Streets)
.FirstOrDefaultAsync(c => c.Id == id);
}
public async Task UpdateAsync(City city)
{
_dbContext.Cities.Update(city);
await _dbContext.SaveChangesAsync();
}
}
}

View File

@ -0,0 +1,47 @@
using Domain.Entities;
using Domain.Repository;
using Microsoft.EntityFrameworkCore;
namespace Persistence.Repositories
{
public class RegionRepository : IRegionRepository
{
public readonly RepositoryDbContext _dbContext;
public RegionRepository(RepositoryDbContext dbContext)
{
_dbContext = dbContext;
}
public async Task AddAsync(Region region)
{
await _dbContext.Regions.AddAsync(region);
await _dbContext.SaveChangesAsync();
}
public async Task DeleteAsync(Region region)
{
_dbContext.Regions.Remove(region);
await _dbContext.SaveChangesAsync();
}
public async Task<List<Region>> GetAllAsync()
{
return await _dbContext.Regions
.Include(r => r.Cities)
.ToListAsync();
}
public async Task<Region> GetByIdAsync(Guid id)
{
return await _dbContext.Regions
.Include(r => r.Cities)
.FirstOrDefaultAsync(r => r.Id == id);
}
public async Task UpdateAsync(Region region)
{
_dbContext.Regions.Update(region);
await _dbContext.SaveChangesAsync();
}
}
}

View File

@ -0,0 +1,46 @@
using Domain.Entities;
using Domain.Repository;
using Microsoft.EntityFrameworkCore;
namespace Persistence.Repositories
{
public class StreetRepository : IStreetRepository
{
public readonly RepositoryDbContext _dbContext;
public StreetRepository(RepositoryDbContext dbContext)
{
_dbContext = dbContext;
}
public async Task AddAsync(Street street)
{
await _dbContext.Streets.AddAsync(street);
await _dbContext.SaveChangesAsync();
}
public async Task DeleteAsync(Street street)
{
_dbContext.Streets.Remove(street);
await _dbContext.SaveChangesAsync();
}
public async Task<List<Street>> GetAllAsync()
{
return await _dbContext.Streets
.Include(s => s.City)
.ToListAsync();
}
public async Task<Street> GetByIdAsync(Guid id)
{
return await _dbContext.Streets
.Include(s => s.City)
.FirstOrDefaultAsync(s => s.Id == id);
}
public async Task UpdateAsync(Street street)
{
_dbContext.Streets.Update(street);
await _dbContext.SaveChangesAsync();
}
}
}

View File

@ -0,0 +1,32 @@
using Domain.Entities;
using Microsoft.EntityFrameworkCore;
namespace Persistence
{
public class RepositoryDbContext : DbContext
{
public RepositoryDbContext(DbContextOptions options) : base(options) { }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (optionsBuilder.IsConfigured == false)
{
optionsBuilder.UseNpgsql(@"
Host=localhost;
Port=5432;
Database=AdressDirectory;
Username=postgres;
Password=postgres");
}
base.OnConfiguring(optionsBuilder);
}
public DbSet<Region> Regions { get; set; }
public DbSet<City> Cities { get; set; }
public DbSet<Street> Streets { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfigurationsFromAssembly(typeof(RepositoryDbContext).Assembly);
}
}
}

View File

@ -0,0 +1,13 @@
using Contracts;
namespace Services.Abstractions
{
public interface ICityService
{
Task<CityDto> GetByIdAsync(Guid id);
Task<List<CityDto>> GetAllAsync();
Task<CityDto> CreateAsync(CityDtoForCreate cityDto);
Task UpdateAsync(Guid cityId, CityDtoForUpdate city);
Task DeleteAsync(Guid cityId);
}
}

View File

@ -0,0 +1,13 @@
using Contracts;
namespace Services.Abstractions
{
public interface IRegionService
{
Task<RegionDto> GetByIdAsync(Guid id);
Task<List<RegionDto>> GetAllAsync();
Task<RegionDto> CreateAsync(RegionDtoForCreate regionDto);
Task UpdateAsync(Guid regionId, RegionDtoForUpdate regionDto);
Task DeleteAsync(Guid regionId);
}
}

View File

@ -0,0 +1,13 @@
using Contracts;
namespace Services.Abstractions
{
public interface IStreetService
{
Task<StreetDto> GetByIdAsync(Guid id);
Task<List<StreetDto>> GetAllAsync();
Task<StreetDto> CreateAsync(StreetDtoForCreate streetDto);
Task UpdateAsync(Guid streetId, StreetDtoForUpdate street);
Task DeleteAsync(Guid streetId);
}
}

View File

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Contracts\Contracts.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,33 @@
using Domain.Entities;
using Domain.Repository;
namespace Services
{
public class CityService : ICityRepository
{
public Task AddAsync(City city)
{
throw new NotImplementedException();
}
public Task DeleteAsync(City city)
{
throw new NotImplementedException();
}
public Task<List<City>> GetAllAsync()
{
throw new NotImplementedException();
}
public Task<City> GetByIdAsync(Guid id)
{
throw new NotImplementedException();
}
public Task UpdateAsync(City city)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,24 @@
using AutoMapper;
using Contracts;
using Domain.Entities;
namespace Services.Profiles
{
public class MappingProfile : Profile
{
public MappingProfile()
{
CreateMap<Region, RegionDto>().ReverseMap();
CreateMap<Region, RegionDtoForCreate>().ReverseMap();
CreateMap<Region, RegionDtoForUpdate>().ReverseMap();
CreateMap<City, CityDto>().ReverseMap();
CreateMap<City, CityDtoForCreate>().ReverseMap();
CreateMap<City, CityDtoForUpdate>().ReverseMap();
CreateMap<Street, StreetDto>().ReverseMap();
CreateMap<Street, StreetDtoForCreate>().ReverseMap();
CreateMap<Street, StreetDtoForUpdate>().ReverseMap();
}
}
}

View File

@ -0,0 +1,73 @@
using AutoMapper;
using Contracts;
using Domain.Entities;
using Domain.Repository;
using Services.Abstractions;
namespace Services
{
public class RegionService : IRegionService
{
private readonly IRegionRepository _regionRepository;
private readonly IMapper _mapper;
public RegionService(IRegionRepository regionRepository, IMapper mapper)
{
_regionRepository = regionRepository;
_mapper = mapper;
}
public async Task<RegionDto> CreateAsync(RegionDtoForCreate regionDto)
{
var region = _mapper.Map<Region>(regionDto);
await _regionRepository.AddAsync(region);
return _mapper.Map<RegionDto>(region);
//создавать сразу с городами ?
}
public async Task DeleteAsync(Guid regionId)
{
var region = await _regionRepository.GetByIdAsync(regionId);
if (region == null)
{
throw new KeyNotFoundException("Region not found");
}
await _regionRepository.DeleteAsync(region);
}
public async Task<List<RegionDto>> GetAllAsync()
{
var regions = await _regionRepository.GetAllAsync();
return _mapper.Map<List<RegionDto>>(regions);
}
public async Task<RegionDto> GetByIdAsync(Guid id)
{
var region = await _regionRepository.GetByIdAsync(id);
if (region == null)
{
throw new KeyNotFoundException("Region not found.");
}
return _mapper.Map<RegionDto>(region);
}
public async Task UpdateAsync(Guid regionId, RegionDtoForUpdate regionDto)
{
var region = await _regionRepository.GetByIdAsync(regionId);
if (region == null)
{
throw new KeyNotFoundException("Region not found.");
}
region.Name = regionDto.Name;
region.Code = regionDto.Code;
//дописать добавление городов
region.Cities.Add
}
}
}

View File

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="13.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Services.Abstractions\Services.Abstractions.csproj" />
</ItemGroup>
</Project>