-
Notifications
You must be signed in to change notification settings - Fork 24
Казаков Андрей Лаб. 1 Группа 6513 #15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
3eb0932
27f7867
c36dd20
68dcf77
f7c703c
58725bb
06de5f2
361302a
e55fc94
adec247
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,5 +6,5 @@ | |
| } | ||
| }, | ||
| "AllowedHosts": "*", | ||
| "BaseAddress": "" | ||
| "BaseAddress": "https://localhost:7106/api/employee" | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk.Web"> | ||
|
|
||
| <PropertyGroup> | ||
| <TargetFramework>net8.0</TargetFramework> | ||
| <Nullable>enable</Nullable> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="Aspire.StackExchange.Redis.DistributedCaching" Version="13.1.1" /> | ||
| <PackageReference Include="Bogus" Version="35.6.5" /> | ||
| <PackageReference Include="Microsoft.Extensions.Caching.Redis" Version="2.3.0" /> | ||
| <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="10.0.3" /> | ||
| <PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <ProjectReference Include="..\Client.Wasm\Client.Wasm.csproj" /> | ||
| <ProjectReference Include="..\CompanyEmployee.Domain\CompanyEmployee.Domain.csproj" /> | ||
| <ProjectReference Include="..\CompanyEmployee.ServiceDefaults\CompanyEmployee.ServiceDefaults.csproj" /> | ||
| </ItemGroup> | ||
|
|
||
| <ProjectExtensions><VisualStudio><UserProperties properties_4launchsettings_1json__JsonSchema="" /></VisualStudio></ProjectExtensions> | ||
|
|
||
| </Project> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| @CompanyEmployee.Api_HostAddress = http://localhost:5121 | ||
|
|
||
| GET {{CompanyEmployee.Api_HostAddress}}/weatherforecast/ | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Очень интересный документ с маршрутом к эндпоинту, которого у тебя в софте нет |
||
| Accept: application/json | ||
|
|
||
| ### | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| using CompanyEmployee.Api.Services; | ||
| using CompanyEmployee.Domain.Entity; | ||
| using Microsoft.AspNetCore.Mvc; | ||
|
|
||
| namespace CompanyEmployee.Api.Controllers; | ||
|
|
||
| /// <summary> | ||
| /// Контроллер для работы с сотрудниками. | ||
| /// </summary> | ||
| [ApiController] | ||
|
Comment on lines
+9
to
+10
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Добавить параметры праймари конструктора в саммари |
||
| [Route("api/[controller]")] | ||
| public class EmployeeController : ControllerBase | ||
| { | ||
| private readonly IEmployeeService _employeeService; | ||
| private readonly ILogger<EmployeeController> _logger; | ||
|
|
||
| public EmployeeController(IEmployeeService employeeService, ILogger<EmployeeController> logger) | ||
| { | ||
| _employeeService = employeeService; | ||
| _logger = logger; | ||
| } | ||
|
Comment on lines
+14
to
+21
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Использовать праймари конструктор |
||
|
|
||
| /// <summary> | ||
| /// Получить сгенерированного сотрудника. | ||
| /// </summary> | ||
| [HttpGet] | ||
| [ProducesResponseType(typeof(Employee), StatusCodes.Status200OK)] | ||
| public async Task<ActionResult<Employee>> GetEmployee(int? seed, CancellationToken cancellationToken) | ||
| { | ||
| _logger.LogInformation("Запрос на получение сотрудника с seed: {Seed}", seed); | ||
| var employee = await _employeeService.GetEmployeeAsync(seed, cancellationToken); | ||
| return Ok(employee); | ||
|
Comment on lines
+30
to
+32
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Точно не надо какую-нибудь обработку исключений соорудить? |
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| using CompanyEmployee.Api.Services; | ||
|
|
||
| var builder = WebApplication.CreateBuilder(args); | ||
|
|
||
| builder.AddServiceDefaults(); | ||
| builder.AddRedisDistributedCache("redis"); | ||
|
|
||
| builder.Services.AddControllers(); | ||
| builder.Services.AddEndpointsApiExplorer(); | ||
| builder.Services.AddSwaggerGen(); | ||
|
|
||
| builder.Services.AddCors(options => | ||
| { | ||
| options.AddPolicy("wasm", policy => | ||
| { | ||
| policy.AllowAnyOrigin() | ||
| .WithMethods("GET") | ||
| .WithHeaders("Content-Type"); | ||
| }); | ||
| }); | ||
|
|
||
| builder.Services.AddSingleton<IEmployeeGenerator, EmployeeGenerator>(); | ||
| builder.Services.AddScoped<IEmployeeService, EmployeeService>(); | ||
|
|
||
| var app = builder.Build(); | ||
|
|
||
| if (app.Environment.IsDevelopment()) | ||
| { | ||
| app.UseSwagger(); | ||
| app.UseSwaggerUI(); | ||
| } | ||
|
|
||
| app.MapDefaultEndpoints(); | ||
| app.UseHttpsRedirection(); | ||
| app.UseCors("wasm"); | ||
| app.UseAuthorization(); | ||
| app.MapControllers(); | ||
|
|
||
| app.Run(); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| { | ||
| "$schema": "http://json.schemastore.org/launchsettings.json", | ||
| "iisSettings": { | ||
| "windowsAuthentication": false, | ||
| "anonymousAuthentication": true, | ||
| "iisExpress": { | ||
| "applicationUrl": "http://localhost:56739", | ||
| "sslPort": 44378 | ||
| } | ||
| }, | ||
| "profiles": { | ||
| "http": { | ||
| "commandName": "Project", | ||
| "dotnetRunMessages": true, | ||
| "launchBrowser": true, | ||
| "launchUrl": "swagger", | ||
| "applicationUrl": "http://localhost:5121", | ||
| "environmentVariables": { | ||
| "ASPNETCORE_ENVIRONMENT": "Development" | ||
| } | ||
| }, | ||
| "https": { | ||
| "commandName": "Project", | ||
| "dotnetRunMessages": true, | ||
| "launchBrowser": true, | ||
| "launchUrl": "swagger", | ||
| "applicationUrl": "https://localhost:7106;http://localhost:5121", | ||
| "environmentVariables": { | ||
| "ASPNETCORE_ENVIRONMENT": "Development" | ||
| } | ||
| }, | ||
| "IIS Express": { | ||
| "commandName": "IISExpress", | ||
| "launchBrowser": true, | ||
| "launchUrl": "swagger", | ||
| "environmentVariables": { | ||
| "ASPNETCORE_ENVIRONMENT": "Development" | ||
| } | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| using Bogus; | ||
| using Bogus.DataSets; | ||
| using CompanyEmployee.Domain.Entity; | ||
| using System.Xml.Linq; | ||
|
|
||
| namespace CompanyEmployee.Api.Services; | ||
|
|
||
| public class EmployeeGenerator : IEmployeeGenerator | ||
| { | ||
| private readonly ILogger<EmployeeGenerator> _logger; | ||
| private readonly string[] _professions = { "Developer", "Manager", "Analyst", "Designer", "QA" }; | ||
| private readonly string[] _suffixes = { "Junior", "Middle", "Senior" }; | ||
|
|
||
| public EmployeeGenerator(ILogger<EmployeeGenerator> logger) | ||
| { | ||
| _logger = logger; | ||
| } | ||
|
Comment on lines
+14
to
+17
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 6 дотнет вышел в 2021 году, в какой временной петле ты существуешь без праймари конструкторов? |
||
|
|
||
| /// <summary> | ||
| /// Генератор сотрудника | ||
| /// </summary> | ||
| public Employee Generate(int? seed = null) | ||
| { | ||
| if (seed.HasValue) | ||
| Randomizer.Seed = new Random(seed.Value); | ||
|
|
||
| var faker = new Faker("ru"); | ||
|
|
||
| var gender = faker.PickRandom<Bogus.DataSets.Name.Gender>(); | ||
| var firstName = faker.Name.FirstName(gender); | ||
| var lastName = faker.Name.LastName(gender); | ||
| var patronymicBase = faker.Name.FirstName(Name.Gender.Male); | ||
| var patronymic = gender == Name.Gender.Male | ||
| ? patronymicBase + "ович" | ||
| : patronymicBase + "овна"; | ||
| var fullName = $"{lastName} {firstName} {patronymic}"; | ||
|
|
||
| var profession = faker.PickRandom(_professions); | ||
| var suffix = faker.PickRandom(_suffixes); | ||
| var position = $"{profession} {suffix}".Trim(); | ||
|
|
||
| var department = faker.Commerce.Department(); | ||
|
|
||
| var hireDate = DateOnly.FromDateTime(faker.Date.Past(10).ToUniversalTime()); | ||
|
|
||
| var salary = suffix switch | ||
| { | ||
| "Junior" => faker.Random.Decimal(30000, 60000), | ||
| "Middle" => faker.Random.Decimal(60000, 100000), | ||
| "Senior" => faker.Random.Decimal(100000, 180000), | ||
| _ => faker.Random.Decimal(40000, 80000) | ||
| }; | ||
| salary = Math.Round(salary, 2); | ||
|
|
||
| var email = faker.Internet.Email(firstName, lastName); | ||
| var phone = faker.Phone.PhoneNumber("+7(###)###-##-##"); | ||
| var isTerminated = faker.Random.Bool(0.1f); | ||
|
|
||
| DateOnly? terminationDate = null; | ||
| if (isTerminated) | ||
| { | ||
| var termDate = faker.Date.Between(hireDate.ToDateTime(TimeOnly.MinValue), DateTime.Now); | ||
| terminationDate = DateOnly.FromDateTime(termDate); | ||
| } | ||
|
|
||
| var employee = new Employee | ||
| { | ||
| Id = faker.Random.Int(1, 100000), | ||
| FullName = fullName, | ||
| Position = position, | ||
| Department = department, | ||
| HireDate = hireDate, | ||
| Salary = salary, | ||
| Email = email, | ||
| Phone = phone, | ||
| IsTerminated = isTerminated, | ||
| TerminationDate = terminationDate | ||
| }; | ||
|
Comment on lines
+29
to
+78
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Переписать все через |
||
|
|
||
| _logger.LogInformation("Сгенерирован новый сотрудник: {@Employee}", employee); | ||
| return employee; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| using CompanyEmployee.Domain.Entity; | ||
| using Microsoft.Extensions.Caching.Distributed; | ||
| using System.Text.Json; | ||
|
|
||
| namespace CompanyEmployee.Api.Services; | ||
|
|
||
| /// <summary> | ||
| /// Реализация сервиса сотрудников с кэшированием в Redis через IDistributedCache. | ||
| /// </summary> | ||
| public class EmployeeService : IEmployeeService | ||
| { | ||
| private readonly IEmployeeGenerator _generator; | ||
| private readonly IDistributedCache _cache; | ||
| private readonly ILogger<EmployeeService> _logger; | ||
| private readonly DistributedCacheEntryOptions _cacheOptions; | ||
|
Comment on lines
+10
to
+15
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. И службу эту, по-хорошему, нужно отрефакторить, чтобы srp не нарушался |
||
|
|
||
| public EmployeeService(IEmployeeGenerator generator, IDistributedCache cache, ILogger<EmployeeService> logger) | ||
| { | ||
| _generator = generator; | ||
| _cache = cache; | ||
| _logger = logger; | ||
| _cacheOptions = new DistributedCacheEntryOptions | ||
| { | ||
| AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5) | ||
| }; | ||
| } | ||
|
Comment on lines
+17
to
+26
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| /// <summary> | ||
| /// Получает сотрудника. | ||
| /// </summary> | ||
|
Comment on lines
+28
to
+30
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| public async Task<Employee> GetEmployeeAsync(int? seed, CancellationToken cancellationToken = default) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ставить суффикс Async имеет смысл только при наличии в том же классе синхронного метода с тем же названием. Синхронного метода я тут не наблюдаю
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Вообще, мне не нравится этот метод, в нем намешано как минимум три вектора изменений код, отрефактори его |
||
| { | ||
| var cacheKey = seed.HasValue ? $"employee:seed:{seed}" : $"employee:random:{Guid.NewGuid()}"; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| _logger.LogDebug("Попытка получения сотрудника из кэша по ключу {CacheKey}", cacheKey); | ||
|
|
||
| var cachedJson = await _cache.GetStringAsync(cacheKey, cancellationToken); | ||
| if (cachedJson != null) | ||
| { | ||
| _logger.LogInformation("Сотрудник найден в кэше по ключу {CacheKey}", cacheKey); | ||
| var employee = JsonSerializer.Deserialize<Employee>(cachedJson); | ||
| return employee!; | ||
| } | ||
|
Comment on lines
+37
to
+43
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. В текущем виде ошибка работы кэша положит тебе приложение, а так быть не должно |
||
|
|
||
| _logger.LogInformation("Сотрудник не найден в кэше, генерация нового. Seed: {Seed}", seed); | ||
| var newEmployee = _generator.Generate(seed); | ||
|
|
||
| var serialized = JsonSerializer.Serialize(newEmployee); | ||
| await _cache.SetStringAsync(cacheKey, serialized, _cacheOptions, cancellationToken); | ||
| _logger.LogDebug("Сгенерированный сотрудник сохранён в кэш по ключу {CacheKey}", cacheKey); | ||
|
Comment on lines
+46
to
+50
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Аналогично |
||
|
|
||
| return newEmployee; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| using CompanyEmployee.Domain.Entity; | ||
|
|
||
| namespace CompanyEmployee.Api.Services; | ||
|
|
||
| public interface IEmployeeGenerator | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Нет саммари |
||
| { | ||
| /// <summary> | ||
| /// Генерирует нового сотрудника. | ||
| /// </summary> | ||
| public Employee Generate(int? seed = null); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| using CompanyEmployee.Domain.Entity; | ||
|
|
||
| namespace CompanyEmployee.Api.Services; | ||
|
|
||
| public interface IEmployeeService | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Тоже нет саммари |
||
| { | ||
| /// <summary> | ||
| /// Получает сотрудника. | ||
| /// </summary> | ||
| public Task<Employee> GetEmployeeAsync(int? seed, CancellationToken cancellationToken = default); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| { | ||
| "Logging": { | ||
| "LogLevel": { | ||
| "Default": "Information", | ||
| "Microsoft.AspNetCore": "Warning" | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| { | ||
| "Logging": { | ||
| "LogLevel": { | ||
| "Default": "Information", | ||
| "Microsoft.AspNetCore": "Warning" | ||
| } | ||
| }, | ||
| "AllowedHosts": "*" | ||
| } |

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Зачем тебе майкрософтовские пакеты, когда ты уже пользуешься аспаеровским?