From c2d982454385c7f4eb4182191d853e8ba50cc711 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D1=80=D0=B8=D0=BD=D0=B0?= Date: Sun, 5 Apr 2026 01:32:12 +0400 Subject: [PATCH 1/4] add response time and student info middleware --- TaskHub/Api/Api.csproj | 4 +-- .../Middleware/ResponseTimeMiddleware.cs.cs | 28 +++++++++++++++++++ .../Api/Middleware/StudentInfoMiddleware.cs | 24 ++++++++++++++++ TaskHub/Api/StartUp.cs | 4 +++ TaskHub/Dal/Dal.csproj | 6 ++-- .../DatabaseLibrary/DatabaseLibrary.csproj | 6 ++-- .../Libs/LoggingLibrary/LoggingLibrary.csproj | 6 ++-- TaskHub/Logic/Logic.csproj | 4 +-- 8 files changed, 69 insertions(+), 13 deletions(-) create mode 100644 TaskHub/Api/Middleware/ResponseTimeMiddleware.cs.cs create mode 100644 TaskHub/Api/Middleware/StudentInfoMiddleware.cs diff --git a/TaskHub/Api/Api.csproj b/TaskHub/Api/Api.csproj index a6946fa..7405f43 100644 --- a/TaskHub/Api/Api.csproj +++ b/TaskHub/Api/Api.csproj @@ -1,7 +1,7 @@ - net10.0 + net8.0 enable enable @@ -12,7 +12,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/TaskHub/Api/Middleware/ResponseTimeMiddleware.cs.cs b/TaskHub/Api/Middleware/ResponseTimeMiddleware.cs.cs new file mode 100644 index 0000000..1f1b9d1 --- /dev/null +++ b/TaskHub/Api/Middleware/ResponseTimeMiddleware.cs.cs @@ -0,0 +1,28 @@ +using System.Diagnostics; + +namespace Api.Middleware +{ + public class ResponseTimeMiddleware + { + private readonly RequestDelegate _next; + + public ResponseTimeMiddleware(RequestDelegate next) + { + _next = next; + } + + public async Task InvokeAsync(HttpContext context) + { + var stopwatch = Stopwatch.StartNew(); + + context.Response.OnStarting(() => + { + stopwatch.Stop(); + context.Response.Headers["X-Response-Time-Ms"] = stopwatch.ElapsedMilliseconds.ToString(); + return Task.CompletedTask; + }); + + await _next(context); + } + } +} diff --git a/TaskHub/Api/Middleware/StudentInfoMiddleware.cs b/TaskHub/Api/Middleware/StudentInfoMiddleware.cs new file mode 100644 index 0000000..23db0ab --- /dev/null +++ b/TaskHub/Api/Middleware/StudentInfoMiddleware.cs @@ -0,0 +1,24 @@ +namespace Api.Middleware +{ + public class StudentInfoMiddleware + { + private readonly RequestDelegate _next; + + public StudentInfoMiddleware(RequestDelegate next) + { + _next = next; + } + + public async Task InvokeAsync(HttpContext context) + { + context.Response.OnStarting(() => + { + context.Response.Headers["X-Student-Name"] = "Tumashova Marina"; + context.Response.Headers["X-Student-Group"] = "RI-240912"; + return Task.CompletedTask; + }); + + await _next(context); + } + } +} diff --git a/TaskHub/Api/StartUp.cs b/TaskHub/Api/StartUp.cs index 9220ca4..1d6c0a2 100644 --- a/TaskHub/Api/StartUp.cs +++ b/TaskHub/Api/StartUp.cs @@ -1,3 +1,4 @@ +using Api.Middleware; using Api.UseCases.Users; using Api.UseCases.Users.Interfaces; using Dal; @@ -81,6 +82,9 @@ public void Configure(IApplicationBuilder app) app.UseRouting(); + app.UseMiddleware(); + app.UseMiddleware(); + app.UseEndpoints(endpoints => { endpoints.MapControllers(); diff --git a/TaskHub/Dal/Dal.csproj b/TaskHub/Dal/Dal.csproj index edb5ba8..1c690cf 100644 --- a/TaskHub/Dal/Dal.csproj +++ b/TaskHub/Dal/Dal.csproj @@ -1,14 +1,14 @@  - net10.0 + net8.0 enable enable - - + + diff --git a/TaskHub/Libs/DatabaseLibrary/DatabaseLibrary.csproj b/TaskHub/Libs/DatabaseLibrary/DatabaseLibrary.csproj index 0c323c8..012f0c1 100644 --- a/TaskHub/Libs/DatabaseLibrary/DatabaseLibrary.csproj +++ b/TaskHub/Libs/DatabaseLibrary/DatabaseLibrary.csproj @@ -1,14 +1,14 @@  - net10.0 + net8.0 enable enable - - + + diff --git a/TaskHub/Libs/LoggingLibrary/LoggingLibrary.csproj b/TaskHub/Libs/LoggingLibrary/LoggingLibrary.csproj index bf06657..ff7786d 100644 --- a/TaskHub/Libs/LoggingLibrary/LoggingLibrary.csproj +++ b/TaskHub/Libs/LoggingLibrary/LoggingLibrary.csproj @@ -1,15 +1,15 @@  - net10.0 + net8.0 enable enable - + - + diff --git a/TaskHub/Logic/Logic.csproj b/TaskHub/Logic/Logic.csproj index a38dfe4..2be5253 100644 --- a/TaskHub/Logic/Logic.csproj +++ b/TaskHub/Logic/Logic.csproj @@ -5,11 +5,11 @@ - + - net10.0 + net8.0 enable enable From 991cf90cf3abcdb863267f44c0c965d89fc70fcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D1=80=D0=B8=D0=BD=D0=B0?= Date: Sun, 5 Apr 2026 14:10:19 +0400 Subject: [PATCH 2/4] homework-2 --- TaskHub/Api/Services/DisposedService.cs | 18 ++++++++ TaskHub/Api/Services/IHasInstanceId.cs | 7 ++++ .../Api/Services/ServiceProviderExtensions.cs | 17 ++++++++ TaskHub/Api/Services/Services.cs | 20 +++++++++ TaskHub/Api/StartUp.cs | 42 +++++++++++++++++++ 5 files changed, 104 insertions(+) create mode 100644 TaskHub/Api/Services/DisposedService.cs create mode 100644 TaskHub/Api/Services/IHasInstanceId.cs create mode 100644 TaskHub/Api/Services/ServiceProviderExtensions.cs create mode 100644 TaskHub/Api/Services/Services.cs diff --git a/TaskHub/Api/Services/DisposedService.cs b/TaskHub/Api/Services/DisposedService.cs new file mode 100644 index 0000000..9a2ce8d --- /dev/null +++ b/TaskHub/Api/Services/DisposedService.cs @@ -0,0 +1,18 @@ +namespace Api.Services +{ + public abstract class DisposedService : IHasInstanceId, IDisposable + { + public Guid InstanceId { get; } = Guid.NewGuid(); + + protected DisposedService() + { + Console.WriteLine($"{GetType().Name} CREATED:{InstanceId}"); + } + + public void Dispose() + { + Console.WriteLine($"{GetType().Name} DISPOSED: {InstanceId}"); + } + } +} + diff --git a/TaskHub/Api/Services/IHasInstanceId.cs b/TaskHub/Api/Services/IHasInstanceId.cs new file mode 100644 index 0000000..d5abf99 --- /dev/null +++ b/TaskHub/Api/Services/IHasInstanceId.cs @@ -0,0 +1,7 @@ +namespace Api.Services +{ + public interface IHasInstanceId + { + Guid InstanceId { get; } + } +} diff --git a/TaskHub/Api/Services/ServiceProviderExtensions.cs b/TaskHub/Api/Services/ServiceProviderExtensions.cs new file mode 100644 index 0000000..9e0da57 --- /dev/null +++ b/TaskHub/Api/Services/ServiceProviderExtensions.cs @@ -0,0 +1,17 @@ +namespace Api.Services +{ + public static class ServiceProviderExtensions + { + public static void CompareServices(this IServiceProvider provider) + where T : IHasInstanceId + { + var first = provider.GetRequiredService(); + var second = provider.GetRequiredService(); + + Console.WriteLine($"Service: {typeof(T).Name}"); + Console.WriteLine($"First: {first.InstanceId}"); + Console.WriteLine($"Second: {second.InstanceId}"); + Console.WriteLine($"Same instance: {ReferenceEquals(first, second)}"); + } + } +} diff --git a/TaskHub/Api/Services/Services.cs b/TaskHub/Api/Services/Services.cs new file mode 100644 index 0000000..7a9a5eb --- /dev/null +++ b/TaskHub/Api/Services/Services.cs @@ -0,0 +1,20 @@ +namespace Api.Services +{ + public interface ISingletonService1 : IHasInstanceId { } + public interface ISingletonService2 : IHasInstanceId { } + + public interface IScopedService1 : IHasInstanceId { } + public interface IScopedService2 : IHasInstanceId { } + + public interface ITransientService1 : IHasInstanceId { } + public interface ITransientService2 : IHasInstanceId { } + + public class SingletonService1 : DisposedService, ISingletonService1 { } + public class SingletonService2 : DisposedService, ISingletonService2 { } + + public class ScopedService1 : DisposedService, IScopedService1 { } + public class ScopedService2 : DisposedService, IScopedService2 { } + + public class TransientService1 : DisposedService, ITransientService1 { } + public class TransientService2 : DisposedService, ITransientService2 { } +} diff --git a/TaskHub/Api/StartUp.cs b/TaskHub/Api/StartUp.cs index 1d6c0a2..7ee8fb3 100644 --- a/TaskHub/Api/StartUp.cs +++ b/TaskHub/Api/StartUp.cs @@ -1,4 +1,5 @@ using Api.Middleware; +using Api.Services; using Api.UseCases.Users; using Api.UseCases.Users.Interfaces; using Dal; @@ -62,6 +63,15 @@ public void ConfigureServices(IServiceCollection services) Version = "v1" }); }); + + services.AddSingleton(); + services.AddSingleton(); + + services.AddScoped(); + services.AddScoped(); + + services.AddTransient(); + services.AddTransient(); } /// @@ -70,6 +80,38 @@ public void ConfigureServices(IServiceCollection services) /// Построитель приложения public void Configure(IApplicationBuilder app) { + using (var scope1 = app.ApplicationServices.CreateScope()) + { + var provider = scope1.ServiceProvider; + + Console.WriteLine("SCOPE 1"); + + provider.CompareServices(); + provider.CompareServices(); + + provider.CompareServices(); + provider.CompareServices(); + + provider.CompareServices(); + provider.CompareServices(); + } + + using (var scope2 = app.ApplicationServices.CreateScope()) + { + var provider = scope2.ServiceProvider; + + Console.WriteLine("SCOPE 2"); + + provider.CompareServices(); + provider.CompareServices(); + + provider.CompareServices(); + provider.CompareServices(); + + provider.CompareServices(); + provider.CompareServices(); + } + if (Environment.IsDevelopment()) { app.UseDeveloperExceptionPage(); From 37c015ca4cb98a1e1f78b159375495d490f9aae7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D1=80=D0=B8=D0=BD=D0=B0?= Date: Sun, 5 Apr 2026 16:10:36 +0400 Subject: [PATCH 3/4] homework-3 --- TaskHub/Api/Api.csproj | 2 +- .../Api/Controllers/Users/UsersController.cs | 5 +++ .../Filters/ResponseTimeHeaderAttribute.cs | 23 +++++++++++++ TaskHub/Api/Filters/SetNameAttribute.cs | 6 ++++ .../Filters/StudentInfoHeadersAttribute.cs | 15 ++++++++ .../Filters/ValidateUserRequestAttribute.cs | 34 +++++++++++++++++++ 6 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 TaskHub/Api/Filters/ResponseTimeHeaderAttribute.cs create mode 100644 TaskHub/Api/Filters/SetNameAttribute.cs create mode 100644 TaskHub/Api/Filters/StudentInfoHeadersAttribute.cs create mode 100644 TaskHub/Api/Filters/ValidateUserRequestAttribute.cs diff --git a/TaskHub/Api/Api.csproj b/TaskHub/Api/Api.csproj index 7405f43..c8bbecd 100644 --- a/TaskHub/Api/Api.csproj +++ b/TaskHub/Api/Api.csproj @@ -1,4 +1,4 @@ - + net8.0 diff --git a/TaskHub/Api/Controllers/Users/UsersController.cs b/TaskHub/Api/Controllers/Users/UsersController.cs index 10a433a..b139e87 100644 --- a/TaskHub/Api/Controllers/Users/UsersController.cs +++ b/TaskHub/Api/Controllers/Users/UsersController.cs @@ -1,3 +1,4 @@ +using Api.Filters; using Api.Controllers.Users.Request; using Api.Controllers.Users.Response; using Api.UseCases.Users.Interfaces; @@ -5,6 +6,9 @@ namespace Api.Controllers.Users; +[ResponseTimeHeader] +[StudentInfoHeaders] + /// /// Контроллер работы с пользователями /// @@ -29,6 +33,7 @@ public UsersController(IManageUserUseCase userUseCase) /// Токен отмены /// Созданный пользователь [HttpPost] + [SetName] public async Task> CreateUserAsync( [FromBody] CreateUserRequest? request, CancellationToken cancellationToken) diff --git a/TaskHub/Api/Filters/ResponseTimeHeaderAttribute.cs b/TaskHub/Api/Filters/ResponseTimeHeaderAttribute.cs new file mode 100644 index 0000000..79b610a --- /dev/null +++ b/TaskHub/Api/Filters/ResponseTimeHeaderAttribute.cs @@ -0,0 +1,23 @@ +using Microsoft.AspNetCore.Mvc.Filters; +using System.Diagnostics; + +namespace Api.Filters +{ + public class ResponseTimeHeaderAttribute : ActionFilterAttribute + { + private Stopwatch _stopwatch; + + public override void OnActionExecuting(ActionExecutingContext context) + { + _stopwatch = Stopwatch.StartNew(); + } + + public override void OnActionExecuted(ActionExecutedContext context) + { + _stopwatch.Stop(); + + context.HttpContext.Response.Headers["X-Response-Time-Ms"] = + _stopwatch.ElapsedMilliseconds.ToString(); + } + } +} diff --git a/TaskHub/Api/Filters/SetNameAttribute.cs b/TaskHub/Api/Filters/SetNameAttribute.cs new file mode 100644 index 0000000..523ccb1 --- /dev/null +++ b/TaskHub/Api/Filters/SetNameAttribute.cs @@ -0,0 +1,6 @@ +namespace Api.Filters +{ + public class SetNameAttribute : ValidateUserRequestAttribute + { + } +} diff --git a/TaskHub/Api/Filters/StudentInfoHeadersAttribute.cs b/TaskHub/Api/Filters/StudentInfoHeadersAttribute.cs new file mode 100644 index 0000000..35488c3 --- /dev/null +++ b/TaskHub/Api/Filters/StudentInfoHeadersAttribute.cs @@ -0,0 +1,15 @@ +using Microsoft.AspNetCore.Mvc.Filters; + +namespace Api.Filters +{ + public class StudentInfoHeadersAttribute : ActionFilterAttribute + { + public override void OnActionExecuted(ActionExecutedContext context) + { + var headers = context.HttpContext.Request.Headers; + + headers["X-Student-Name"] = "Tumashova Marina"; + headers["X-Student-Group"] = "RI-240912"; + } + } +} diff --git a/TaskHub/Api/Filters/ValidateUserRequestAttribute.cs b/TaskHub/Api/Filters/ValidateUserRequestAttribute.cs new file mode 100644 index 0000000..8d44de0 --- /dev/null +++ b/TaskHub/Api/Filters/ValidateUserRequestAttribute.cs @@ -0,0 +1,34 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; +using System.Reflection; + +namespace Api.Filters +{ + public class ValidateUserRequestAttribute : ActionFilterAttribute + { + public override void OnActionExecuting(ActionExecutingContext context) + { + var request = context.ActionArguments.Values.FirstOrDefault(); + + if (request == null) + { + context.Result = new BadRequestObjectResult("нет тела запроса"); + return; + } + + var nameProperty = request.GetType().GetProperty("Name"); + + if (nameProperty == null) + { + return; + } + + var nameValue = nameProperty.GetValue(request)?.ToString(); + + if (string.IsNullOrWhiteSpace(nameValue)) + { + context.Result = new BadRequestObjectResult("нет имени"); + } + } + } +} From 7f819944aad25911527fb21e45f04509f9248ba6 Mon Sep 17 00:00:00 2001 From: Meowmeow-me8ow Date: Sun, 5 Apr 2026 16:15:59 +0400 Subject: [PATCH 4/4] Add files via upload --- 3.1.png | Bin 0 -> 7767 bytes 3.2.png | Bin 0 -> 24045 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 3.1.png create mode 100644 3.2.png diff --git a/3.1.png b/3.1.png new file mode 100644 index 0000000000000000000000000000000000000000..938ac35fc99adeba021fb9e300268c724e7241d2 GIT binary patch literal 7767 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 B+<*W8 literal 0 HcmV?d00001 diff --git a/3.2.png b/3.2.png new file mode 100644 index 0000000000000000000000000000000000000000..107fbac17d749e48811a3e410953da392971cb05 GIT binary patch literal 24045 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 literal 0 HcmV?d00001