Conversation
danlla
left a comment
There was a problem hiding this comment.
Выглядит немного как оверинжиниринг, много интерфейсов, у которых больше одной имплементации точно не будет, выделение в либу генератора, хотя он неплохо бы смотрелся как сервис в апи
В принципе оно выглядит хорошо и если так хочется, пусть так будет
При старте Apire отдельно в браузере запускается клиент, что не очень удобно, можно отключить это в launchsettings.json клиента
| var faker = new Faker(); | ||
|
|
||
| var status = faker.PickRandom(CreditDictionaries.Statuses); | ||
|
|
||
| var submissionDate = DateOnly.FromDateTime( | ||
| faker.Date.Between(DateTime.Now.AddYears(-2), DateTime.Now)); | ||
|
|
||
| DateOnly? decisionDate = null; | ||
| decimal? approvedAmount = null; | ||
|
|
||
| var requested = Math.Round(faker.Random.Decimal(100_000, 10_000_000), 2); | ||
|
|
||
| if (CreditDictionaries.IsTerminal(status)) | ||
| { | ||
| decisionDate = submissionDate.AddDays(faker.Random.Int(1, 30)); | ||
|
|
||
| if (status == "Одобрена") | ||
| { | ||
| approvedAmount = Math.Round( | ||
| faker.Random.Decimal(10_000, requested), 2); | ||
| } | ||
| } | ||
|
|
||
| var interestRate = Math.Round( | ||
| faker.Random.Double(centralBankRate, centralBankRate + 10), 2); | ||
|
|
||
| return Task.FromResult(new CreditApplication | ||
| { | ||
| Id = id, | ||
| CreditType = faker.PickRandom(CreditDictionaries.CreditTypes), | ||
| RequestedAmount = requested, | ||
| TermMonths = faker.Random.Int(6, 360), | ||
| InterestRate = interestRate, | ||
| SubmissionDate = submissionDate, | ||
| HasInsurance = faker.Random.Bool(), | ||
| Status = status, | ||
| DecisionDate = decisionDate, | ||
| ApprovedAmount = approvedAmount | ||
| }); |
There was a problem hiding this comment.
Всю генерацию лучше сделать в виде:
var faker = new Faker<CreditApplication>()
.RuleFor(c => c.Status, f => f.PickRandom(CreditDictionaries.Statuses))
...
return faker.Generate();сам объект faker можно объявить полем/свойством и инициализировать при создании генератора
| if (!string.IsNullOrEmpty(cached)) | ||
| { | ||
| logger.LogInformation("Cache HIT {CacheKey}", cacheKey); | ||
| return JsonSerializer.Deserialize<CreditApplication>(cached)!; |
There was a problem hiding this comment.
Теоретически возможно ситуация, что в кэше лежит мусор, который не сможет быть десериализован
Так что тут лучше не использовать null-forgiving operator, а проверить на null и вернуть если все нормально, а если не нормально, то код ниже сгенерирует новый объект по заданному ключу
|
|
||
| var options = new DistributedCacheEntryOptions | ||
| { | ||
| AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(10) |
| ILogger<CreditService> logger) | ||
| : ICreditService | ||
| { | ||
| public async Task<CreditApplication> GetAsync(int id, CancellationToken ct) |
There was a problem hiding this comment.
Все тело метода стоит в try catch обернуть
|
|
||
| builder.AddRedisDistributedCache("credit-cache"); | ||
|
|
||
| var centralBankRate = builder.Configuration.GetValue<double>("CreditGenerator:CentralBankRate", 16.0); |
There was a problem hiding this comment.
<double> тут не нужен, тип по дефолтному значение подтягивается
| /// <param name="ct">Токен отмены для асинхронной операции.</param> | ||
| /// <returns>HTTP 200 с объектом заявки при успешном получении.</returns> | ||
| [HttpGet] | ||
| public async Task<IActionResult> Get([FromQuery] int id, CancellationToken ct) |
There was a problem hiding this comment.
Если использовать сваггер, то нужно нормально настроить генерацию OpenApi:
Task<ActionResult<CreditApplication>>Только после этого нужно будет добавить еще xml файл из CreditApp.Domain, чтобы у CreditApplication в OpenApi было описание
Можно так же накинуть атрибуты, по типу ProduceResponseType
| public class CreditApplicationGenerator(double centralBankRate) | ||
| : ICreditApplicationGenerator | ||
| { | ||
| public Task<CreditApplication> GenerateAsync(int id, CancellationToken ct) |
There was a problem hiding this comment.
CancellationToken нигде не используется же
| builder.Services.AddCors(options => | ||
| { | ||
| options.AddPolicy("DefaultCors", | ||
| policy => policy.AllowAnyOrigin() | ||
| .AllowAnyHeader() | ||
| .AllowAnyMethod()); | ||
| }); |
There was a problem hiding this comment.
Лучше cors настроить нормально:
Брать из appsettings.json допустимые origins
Для app.Environment.IsDevelopment() можно оставить доступ всем
| <UnorderedListItem>Выполнена <Strong>Фамилией Именем 65ХХ</Strong> </UnorderedListItem> | ||
| <UnorderedListItem><Link To="https://puginarug.com/">Ссылка на форк</Link></UnorderedListItem> | ||
| <UnorderedListItem>Номер <Strong>№1 "Кэширование"</Strong></UnorderedListItem> | ||
| <UnorderedListItem>Вариант <Strong>№2 "Кредитная заявка"</Strong></UnorderedListItem> |
| <ProjectReference Include="..\CreditApp.Application\CreditApp.Application.csproj" /> | ||
| <ProjectReference Include="..\CreditApp.Domain\CreditApp.Domain.csproj" /> | ||
| <ProjectReference Include="..\CreditApp.Infrastructure\CreditApp.Infrastructure.csproj" /> | ||
| <ProjectReference Include="..\CreditApp\CreditApp.ServiceDefaults\CreditApp.ServiceDefaults.csproj" /> |
There was a problem hiding this comment.
Референс на проект есть, но код из него нигде не используется
ФИО: Сукач Данил
Номер группы: 6511
Номер лабораторной: 1
Номер варианта: 15
Краткое описание предметной области: Кредитная заявка
**Краткое описание добавленных фич:**Добавлен сервис генерации и кэширование через redis