-
Notifications
You must be signed in to change notification settings - Fork 24
Сукач Данил Лаб. 1 Группа 6511 #6
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
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 |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| using CreditApp.Application.Interfaces; | ||
| using Microsoft.AspNetCore.Mvc; | ||
|
|
||
| namespace CreditApp.Api.Controllers; | ||
|
|
||
| /// <summary> | ||
| /// Контроллер для работы с кредитными заявками через HTTP API. | ||
| /// Реализует конечную точку получения заявки по идентификатору. | ||
| /// <param name="creditService">Сервис для получения данных кредитных заявок.</param> | ||
| /// <param name="logger">Логгер для записи событий и ошибок.</param> | ||
| /// </summary> | ||
| [Route("api/[controller]")] | ||
| [ApiController] | ||
| public class CreditController( | ||
| ICreditService creditService, | ||
| ILogger<CreditController> logger | ||
| ) : ControllerBase | ||
| { | ||
| /// <summary> | ||
| /// Получает кредитную заявку по идентификатору. | ||
| /// </summary> | ||
| /// <param name="id">Идентификатор запрашиваемой заявки (передаётся в строке запроса).</param> | ||
| /// <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. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Если использовать сваггер, то нужно нормально настроить генерацию OpenApi: Task<ActionResult<CreditApplication>>Только после этого нужно будет добавить еще xml файл из Можно так же накинуть атрибуты, по типу |
||
| { | ||
| logger.LogInformation("Request for credit {CreditId} started", id); | ||
|
|
||
| var result = await creditService.GetAsync(id, ct); | ||
|
|
||
| logger.LogInformation("Request for credit {CreditId} completed", id); | ||
|
|
||
| return Ok(result); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk.Web"> | ||
|
|
||
| <PropertyGroup> | ||
| <TargetFramework>net8.0</TargetFramework> | ||
| <Nullable>enable</Nullable> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| <GenerateDocumentationFile>true</GenerateDocumentationFile> | ||
| <NoWarn>$(NoWarn);1591</NoWarn> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="Aspire.StackExchange.Redis" Version="13.1.1" /> | ||
| <PackageReference Include="Aspire.StackExchange.Redis.DistributedCaching" Version="13.1.1" /> | ||
| <PackageReference Include="Swashbuckle.AspNetCore" Version="10.1.3" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <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. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Референс на проект есть, но код из него нигде не используется |
||
| </ItemGroup> | ||
|
|
||
| </Project> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| using CreditApp.Application.Interfaces; | ||
| using CreditApp.Application.Services; | ||
| using CreditApp.Infrastructure.Generators; | ||
| using Microsoft.OpenApi; | ||
| using System.Reflection; | ||
|
|
||
| var builder = WebApplication.CreateBuilder(args); | ||
|
|
||
| builder.AddRedisDistributedCache("credit-cache"); | ||
|
|
||
| var centralBankRate = builder.Configuration.GetValue<double>("CreditGenerator:CentralBankRate", 16.0); | ||
|
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.
|
||
|
|
||
| builder.Services.AddSingleton<ICreditApplicationGenerator>( | ||
| new CreditApplicationGenerator(centralBankRate)); | ||
|
Comment on lines
+13
to
+14
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. А вообще лучше так не делать, если в сервисе появятся зависимости от других сервисов, то придется вручную их тут прописывать |
||
|
|
||
| builder.Services.AddScoped<ICreditService, CreditService>(); | ||
|
|
||
| builder.Services.AddControllers(); | ||
| builder.Services.AddEndpointsApiExplorer(); | ||
| builder.Services.AddSwaggerGen(options => | ||
| { | ||
| var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; | ||
| var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); | ||
| options.IncludeXmlComments(xmlPath); | ||
| }); | ||
|
|
||
| builder.Services.AddCors(options => | ||
| { | ||
| options.AddPolicy("DefaultCors", | ||
| policy => policy.AllowAnyOrigin() | ||
| .AllowAnyHeader() | ||
| .AllowAnyMethod()); | ||
| }); | ||
|
Comment on lines
+27
to
+33
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. Лучше cors настроить нормально: Для |
||
|
|
||
| var app = builder.Build(); | ||
|
|
||
| if (app.Environment.IsDevelopment()) | ||
| { | ||
| app.UseSwagger(); | ||
| app.UseSwaggerUI(c => | ||
| { | ||
| c.SwaggerEndpoint("/swagger/v1/swagger.json", "V1"); | ||
| c.RoutePrefix = string.Empty; | ||
| }); | ||
| } | ||
|
|
||
| app.UseCors("DefaultCors"); | ||
|
|
||
| app.MapControllers(); | ||
|
|
||
| app.Run(); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| { | ||
| "$schema": "http://json.schemastore.org/launchsettings.json", | ||
| "iisSettings": { | ||
| "windowsAuthentication": false, | ||
| "anonymousAuthentication": true, | ||
| "iisExpress": { | ||
| "applicationUrl": "http://localhost:53917", | ||
| "sslPort": 44347 | ||
| } | ||
| }, | ||
| "profiles": { | ||
| "http": { | ||
| "commandName": "Project", | ||
| "dotnetRunMessages": true, | ||
| "launchBrowser": true, | ||
| "applicationUrl": "http://localhost:5022", | ||
| "environmentVariables": { | ||
| "ASPNETCORE_ENVIRONMENT": "Development" | ||
| } | ||
| }, | ||
| "https": { | ||
| "commandName": "Project", | ||
| "dotnetRunMessages": true, | ||
| "launchBrowser": true, | ||
| "applicationUrl": "https://localhost:7084;http://localhost:5022", | ||
| "environmentVariables": { | ||
| "ASPNETCORE_ENVIRONMENT": "Development" | ||
| } | ||
| }, | ||
| "IIS Express": { | ||
| "commandName": "IISExpress", | ||
| "launchBrowser": true, | ||
| "environmentVariables": { | ||
| "ASPNETCORE_ENVIRONMENT": "Development" | ||
| } | ||
| } | ||
| } | ||
| } |
| 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,16 @@ | ||
| { | ||
| "Logging": { | ||
| "LogLevel": { | ||
| "Default": "Information", | ||
| "Microsoft.AspNetCore": "Warning" | ||
| } | ||
| }, | ||
| "AllowedHosts": "*", | ||
| "ConnectionStrings": { | ||
| "redis": "localhost:6379" | ||
| } | ||
| , | ||
| "CreditGenerator": { | ||
| "CentralBankRate": 16.0 | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <TargetFramework>net8.0</TargetFramework> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| <Nullable>enable</Nullable> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="8.0.0" /> | ||
| <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <ProjectReference Include="..\CreditApp.Domain\CreditApp.Domain.csproj" /> | ||
| </ItemGroup> | ||
|
|
||
| </Project> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| using CreditApp.Domain.Entities; | ||
|
|
||
| namespace CreditApp.Application.Interfaces; | ||
|
|
||
| /// <summary> | ||
| /// Генерирует объекты заявок на кредит для тестирования, заполнения демонстрационных данных или инициализации. | ||
| /// Реализации должны создавать и возвращать готовый к использованию экземпляр <see cref="CreditApplication"/>. | ||
| /// </summary> | ||
| public interface ICreditApplicationGenerator | ||
| { | ||
| /// <summary> | ||
| /// Асинхронно генерирует заявку на кредит с указанным идентификатором. | ||
| /// </summary> | ||
| /// <param name="id">Идентификатор создаваемой заявки.</param> | ||
| /// <param name="ct">Токен отмены для асинхронной операции.</param> | ||
| /// <returns>Сгенерированный экземпляр <see cref="CreditApplication"/>.</returns> | ||
| public Task<CreditApplication> GenerateAsync(int id, CancellationToken ct); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| using CreditApp.Domain.Entities; | ||
|
|
||
| namespace CreditApp.Application.Interfaces; | ||
|
|
||
| /// <summary> | ||
| /// Сервис для работы с объектами кредитных заявок. | ||
| /// Предоставляет операции получения и управления заявками в приложении. | ||
| /// </summary> | ||
| public interface ICreditService | ||
| { | ||
| /// <summary> | ||
| /// Асинхронно получает заявку на кредит по её идентификатору. | ||
| /// </summary> | ||
| /// <param name="id">Идентификатор заявки.</param> | ||
| /// <param name="ct">Токен отмены для асинхронной операции.</param> | ||
| /// <returns>Экземпляр <see cref="CreditApplication"/>, соответствующий запрошенному идентификатору.</returns> | ||
| public Task<CreditApplication> GetAsync(int id, CancellationToken ct); | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| using System.Text.Json; | ||
| using CreditApp.Application.Interfaces; | ||
| using CreditApp.Domain.Entities; | ||
| using Microsoft.Extensions.Caching.Distributed; | ||
| using Microsoft.Extensions.Logging; | ||
|
|
||
| namespace CreditApp.Application.Services; | ||
|
|
||
| public class CreditService(IDistributedCache distributedCache, | ||
| ICreditApplicationGenerator generator, | ||
| ILogger<CreditService> logger) | ||
| : ICreditService | ||
| { | ||
| public async Task<CreditApplication> GetAsync(int id, CancellationToken ct) | ||
|
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 = $"Credit_{id}"; | ||
|
|
||
| var cached = await distributedCache.GetStringAsync(cacheKey, ct); | ||
|
|
||
| if (!string.IsNullOrEmpty(cached)) | ||
| { | ||
| logger.LogInformation("Cache HIT {CacheKey}", cacheKey); | ||
| return JsonSerializer.Deserialize<CreditApplication>(cached)!; | ||
|
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("Cache MISS {CacheKey}", cacheKey); | ||
|
|
||
| var credit = await generator.GenerateAsync(id, ct); | ||
|
|
||
| var options = new DistributedCacheEntryOptions | ||
| { | ||
| AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(10) | ||
|
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.
|
||
| }; | ||
|
|
||
| await distributedCache.SetStringAsync( | ||
| cacheKey, | ||
| JsonSerializer.Serialize(credit), | ||
| options, | ||
| ct); | ||
|
|
||
| return credit; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <TargetFramework>net8.0</TargetFramework> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| <Nullable>enable</Nullable> | ||
| </PropertyGroup> | ||
|
|
||
| </Project> |
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.
Вариант 15