diff --git a/4,1.png b/4,1.png new file mode 100644 index 0000000..b61c881 Binary files /dev/null and b/4,1.png differ diff --git a/4,2.png b/4,2.png new file mode 100644 index 0000000..bcad054 Binary files /dev/null and b/4,2.png differ diff --git a/4,3.png b/4,3.png new file mode 100644 index 0000000..d7a24e7 Binary files /dev/null and b/4,3.png differ diff --git a/4,4.png b/4,4.png new file mode 100644 index 0000000..f53e659 Binary files /dev/null and b/4,4.png differ diff --git a/4,5.png b/4,5.png new file mode 100644 index 0000000..8f92752 Binary files /dev/null and b/4,5.png differ diff --git a/4,6.png b/4,6.png new file mode 100644 index 0000000..0cfc06b Binary files /dev/null and b/4,6.png differ diff --git a/4,7.png b/4,7.png new file mode 100644 index 0000000..7764afc Binary files /dev/null and b/4,7.png differ diff --git a/TaskHub/Api/Api.csproj b/TaskHub/Api/Api.csproj index a6946fa..c8bbecd 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/Controllers/Tasks/Request/CreateTaskRequest.cs b/TaskHub/Api/Controllers/Tasks/Request/CreateTaskRequest.cs new file mode 100644 index 0000000..9507259 --- /dev/null +++ b/TaskHub/Api/Controllers/Tasks/Request/CreateTaskRequest.cs @@ -0,0 +1,8 @@ +namespace Api.Controllers.Tasks.Request +{ + public class CreateTaskRequest + { + public string? Title { get; set; } + public Guid UserId { get; set; } + } +} diff --git a/TaskHub/Api/Controllers/Tasks/Request/SetTaskTitleRequest.cs b/TaskHub/Api/Controllers/Tasks/Request/SetTaskTitleRequest.cs new file mode 100644 index 0000000..7e9d631 --- /dev/null +++ b/TaskHub/Api/Controllers/Tasks/Request/SetTaskTitleRequest.cs @@ -0,0 +1,7 @@ +namespace Api.Controllers.Tasks.Request +{ + public class SetTaskTitleRequest + { + public string? Title { get; set; } + } +} diff --git a/TaskHub/Api/Controllers/Tasks/Response/TaskResponse.cs b/TaskHub/Api/Controllers/Tasks/Response/TaskResponse.cs new file mode 100644 index 0000000..f21d312 --- /dev/null +++ b/TaskHub/Api/Controllers/Tasks/Response/TaskResponse.cs @@ -0,0 +1,18 @@ +namespace Api.Controllers.Tasks.Response +{ + public class TaskResponse + { + public Guid Id { get; } + public string? Title { get; } + public Guid CreatedByUserId { get; } + public DateTimeOffset CreatedUtc { get; } + + public TaskResponse(Guid id, string? title, Guid createdByUserId, DateTimeOffset createdUtc) + { + Id = id; + Title = title; + CreatedByUserId = createdByUserId; + CreatedUtc = createdUtc; + } + } +} diff --git a/TaskHub/Api/Controllers/Tasks/TasksController.cs b/TaskHub/Api/Controllers/Tasks/TasksController.cs new file mode 100644 index 0000000..62f898d --- /dev/null +++ b/TaskHub/Api/Controllers/Tasks/TasksController.cs @@ -0,0 +1,60 @@ +using Api.Controllers.Tasks.Request; +using Api.Controllers.Tasks.Response; +using Api.UseCases.Tasks.Interfaces; +using Microsoft.AspNetCore.Mvc; + +namespace Api.Controllers.Tasks; + +[ApiController] +[Route("tasks")] +public class TasksController : ControllerBase +{ + private readonly IManageTaskUseCase _useCase; + + public TasksController(IManageTaskUseCase useCase) + { + _useCase = useCase; + } + + [HttpPost] + public async Task> Create(CreateTaskRequest request, CancellationToken ct) + { + var result = await _useCase.CreateTaskAsync(request.Title, request.UserId, ct); + return Created("", result); + } + + [HttpGet] + public async Task>> GetAll(CancellationToken ct) + { + return Ok(await _useCase.GetAllTasksAsync(ct)); + } + + [HttpGet("{id:guid}")] + public async Task> Get(Guid id, CancellationToken ct) + { + var result = await _useCase.GetTaskByIdAsync(id, ct); + if (result == null) return NotFound(); + return Ok(result); + } + + [HttpPut("{id:guid}/title")] + public async Task SetTitle(Guid id, SetTaskTitleRequest request, CancellationToken ct) + { + await _useCase.SetTaskTitleAsync(id, request.Title!, ct); + return NoContent(); + } + + [HttpDelete("{id:guid}")] + public async Task Delete(Guid id, CancellationToken ct) + { + var deleted = await _useCase.DeleteTaskByIdAsync(id, ct); + return deleted ? NoContent() : NotFound(); + } + + [HttpDelete] + public async Task DeleteAll(CancellationToken ct) + { + await _useCase.DeleteAllTasksAsync(ct); + return NoContent(); + } +} 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("нет имени"); + } + } + } +} 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/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 9220ca4..0d2fcc8 100644 --- a/TaskHub/Api/StartUp.cs +++ b/TaskHub/Api/StartUp.cs @@ -1,5 +1,9 @@ +using Api.Middleware; +using Api.Services; using Api.UseCases.Users; using Api.UseCases.Users.Interfaces; +using Api.UseCases.Tasks; +using Api.UseCases.Tasks.Interfaces; using Dal; using Logic; using Microsoft.OpenApi.Models; @@ -38,7 +42,8 @@ public void ConfigureServices(IServiceCollection services) services.AddLogic(); services.AddScoped(); - + services.AddScoped(); + services.AddCors(options => { options.AddDefaultPolicy(builder => @@ -61,6 +66,15 @@ public void ConfigureServices(IServiceCollection services) Version = "v1" }); }); + + services.AddSingleton(); + services.AddSingleton(); + + services.AddScoped(); + services.AddScoped(); + + services.AddTransient(); + services.AddTransient(); } /// @@ -69,18 +83,53 @@ public void ConfigureServices(IServiceCollection services) /// Построитель приложения public void Configure(IApplicationBuilder app) { - if (Environment.IsDevelopment()) + 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(); app.UseSwagger(); app.UseSwaggerUI(options => { options.SwaggerEndpoint("/swagger/v1/swagger.json", "TaskHub API v1"); }); - } + //} app.UseRouting(); + app.UseMiddleware(); + app.UseMiddleware(); + app.UseEndpoints(endpoints => { endpoints.MapControllers(); diff --git a/TaskHub/Api/UseCases/Tasks/Interfaces/IManageTaskUseCase.cs b/TaskHub/Api/UseCases/Tasks/Interfaces/IManageTaskUseCase.cs new file mode 100644 index 0000000..9572d65 --- /dev/null +++ b/TaskHub/Api/UseCases/Tasks/Interfaces/IManageTaskUseCase.cs @@ -0,0 +1,19 @@ +using Api.Controllers.Tasks.Response; + +namespace Api.UseCases.Tasks.Interfaces +{ + public interface IManageTaskUseCase + { + Task CreateTaskAsync(string? title, Guid userId, CancellationToken cancellationToken); + + Task> GetAllTasksAsync(CancellationToken cancellationToken); + + Task GetTaskByIdAsync(Guid id, CancellationToken cancellationToken); + + Task SetTaskTitleAsync(Guid id, string title, CancellationToken cancellationToken); + + Task DeleteTaskByIdAsync(Guid id, CancellationToken cancellationToken); + + Task DeleteAllTasksAsync(CancellationToken cancellationToken); + } +} diff --git a/TaskHub/Api/UseCases/Tasks/ManageTaskUseCase.cs b/TaskHub/Api/UseCases/Tasks/ManageTaskUseCase.cs new file mode 100644 index 0000000..eb93d89 --- /dev/null +++ b/TaskHub/Api/UseCases/Tasks/ManageTaskUseCase.cs @@ -0,0 +1,57 @@ +using Api.Controllers.Tasks.Response; +using Api.UseCases.Tasks.Interfaces; +using Logic.Tasks.Services.Interfaces; + +namespace Api.UseCases.Tasks; + +internal sealed class ManageTaskUseCase : IManageTaskUseCase +{ + private readonly ITaskService _taskService; + + public ManageTaskUseCase(ITaskService taskService) + { + _taskService = taskService; + } + + public async Task CreateTaskAsync(string? title, Guid userId, CancellationToken cancellationToken) + { + var task = await _taskService.CreateTaskAsync(title, userId, cancellationToken); + + return new TaskResponse(task.Id, task.Title, task.CreatedByUserId, task.CreatedUtc); + } + + public async Task> GetAllTasksAsync(CancellationToken cancellationToken) + { + var tasks = await _taskService.GetAllTasksAsync(cancellationToken); + + return tasks + .Select(x => new TaskResponse(x.Id, x.Title, x.CreatedByUserId, x.CreatedUtc)) + .ToList() + .AsReadOnly(); + } + + public async Task GetTaskByIdAsync(Guid id, CancellationToken cancellationToken) + { + var task = await _taskService.GetTaskByIdAsync(id, cancellationToken); + + if (task == null) + return null; + + return new TaskResponse(task.Id, task.Title, task.CreatedByUserId, task.CreatedUtc); + } + + public async Task SetTaskTitleAsync(Guid id, string title, CancellationToken cancellationToken) + { + await _taskService.SetTaskTitleAsync(id, title, cancellationToken); + } + + public async Task DeleteTaskByIdAsync(Guid id, CancellationToken cancellationToken) + { + return await _taskService.DeleteTaskByIdAsync(id, cancellationToken); + } + + public async Task DeleteAllTasksAsync(CancellationToken cancellationToken) + { + await _taskService.DeleteAllTasksAsync(cancellationToken); + } +} 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/Dal/DalStartUp.cs b/TaskHub/Dal/DalStartUp.cs index f6dfa82..81a8690 100644 --- a/TaskHub/Dal/DalStartUp.cs +++ b/TaskHub/Dal/DalStartUp.cs @@ -1,6 +1,7 @@ using Dal.Context; using Dal.Repositories; using Dal.Repositories.Interfaces; +using Dal.Repositories.Tasks; using DatabaseLibrary; using Microsoft.Extensions.DependencyInjection; @@ -18,6 +19,8 @@ public static class DalStartUp public static void AddDal(this IServiceCollection services) { services.AddDatabase(); + services.AddDatabase(); services.AddScoped(); + services.AddScoped(); } } diff --git a/TaskHub/Dal/Entities/TaskEntity.cs b/TaskHub/Dal/Entities/TaskEntity.cs new file mode 100644 index 0000000..9f8bcba --- /dev/null +++ b/TaskHub/Dal/Entities/TaskEntity.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Dal.Entities +{ + public class TaskEntity + { + public Guid Id { get; set; } + public string? Title { get; set; } + public Guid CreatedByUserId { get; set; } + public DateTimeOffset CreatedUtc { get; set; } + } +} diff --git a/TaskHub/Dal/Repositories/Tasks/ITaskRepository.cs b/TaskHub/Dal/Repositories/Tasks/ITaskRepository.cs new file mode 100644 index 0000000..cf428b5 --- /dev/null +++ b/TaskHub/Dal/Repositories/Tasks/ITaskRepository.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Dal.Entities; + +namespace Dal.Repositories.Tasks +{ + public interface ITaskRepository + { + Task CreateAsync(TaskEntity task); + Task> GetAllAsync(); + Task GetByIdAsync(Guid id); + Task UpdateTitleAsync(Guid id, string title); + Task DeleteAsync(Guid id); + Task DeleteAllAsync(); + } +} diff --git a/TaskHub/Dal/Repositories/Tasks/TaskRepository.cs b/TaskHub/Dal/Repositories/Tasks/TaskRepository.cs new file mode 100644 index 0000000..087cef7 --- /dev/null +++ b/TaskHub/Dal/Repositories/Tasks/TaskRepository.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Dal.Entities; +using Microsoft.EntityFrameworkCore; + +namespace Dal.Repositories.Tasks +{ + public class TaskRepository : ITaskRepository + { + private readonly TaskDbContext _context; + + public TaskRepository(TaskDbContext context) + { + _context = context; + } + + public async Task CreateAsync(TaskEntity task) + { + _context.Tasks.Add(task); + await _context.SaveChangesAsync(); + return task; + } + + public async Task> GetAllAsync() + { + return await _context.Tasks.ToListAsync(); + } + + public async Task GetByIdAsync(Guid id) + { + return await _context.Tasks.FindAsync(id); + } + + public async Task UpdateTitleAsync(Guid id, string title) + { + var task = await _context.Tasks.FindAsync(id); + if (task != null) + { + task.Title = title; + await _context.SaveChangesAsync(); + } + } + + public async Task DeleteAsync(Guid id) + { + var task = await _context.Tasks.FindAsync(id); + if (task == null) return false; + + _context.Tasks.Remove(task); + await _context.SaveChangesAsync(); + return true; + } + + public async Task DeleteAllAsync() + { + _context.Tasks.RemoveRange(_context.Tasks); + await _context.SaveChangesAsync(); + } + } +} diff --git a/TaskHub/Dal/TaskDbContext.cs b/TaskHub/Dal/TaskDbContext.cs new file mode 100644 index 0000000..42caa0c --- /dev/null +++ b/TaskHub/Dal/TaskDbContext.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Dal.Entities; +using Microsoft.EntityFrameworkCore; + +namespace Dal +{ + public class TaskDbContext : DbContext + { + public TaskDbContext(DbContextOptions options) + : base(options) { } + + public DbSet Tasks { get; set; } + } +} 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 diff --git a/TaskHub/Logic/LogicStartUp.cs b/TaskHub/Logic/LogicStartUp.cs index 6fc3e70..5d0a99c 100644 --- a/TaskHub/Logic/LogicStartUp.cs +++ b/TaskHub/Logic/LogicStartUp.cs @@ -1,4 +1,6 @@ -using Logic.Users.Services; +using Logic.Tasks.Services; +using Logic.Tasks.Services.Interfaces; +using Logic.Users.Services; using Logic.Users.Services.Interfaces; using Microsoft.Extensions.DependencyInjection; @@ -16,5 +18,6 @@ public static class LogicStartUp public static void AddLogic(this IServiceCollection services) { services.AddScoped(); + services.AddScoped(); } } \ No newline at end of file diff --git a/TaskHub/Logic/Tasks/Services/Interfaces/ITaskService.cs b/TaskHub/Logic/Tasks/Services/Interfaces/ITaskService.cs new file mode 100644 index 0000000..69069af --- /dev/null +++ b/TaskHub/Logic/Tasks/Services/Interfaces/ITaskService.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Dal.Entities; + +namespace Logic.Tasks.Services.Interfaces; + +public interface ITaskService +{ + Task CreateTaskAsync(string? title, Guid userId, CancellationToken cancellationToken); + + Task> GetAllTasksAsync(CancellationToken cancellationToken); + + Task GetTaskByIdAsync(Guid id, CancellationToken cancellationToken); + + Task SetTaskTitleAsync(Guid id, string title, CancellationToken cancellationToken); + + Task DeleteTaskByIdAsync(Guid id, CancellationToken cancellationToken); + + Task DeleteAllTasksAsync(CancellationToken cancellationToken); +} diff --git a/TaskHub/Logic/Tasks/Services/TaskService.cs b/TaskHub/Logic/Tasks/Services/TaskService.cs new file mode 100644 index 0000000..bbda82d --- /dev/null +++ b/TaskHub/Logic/Tasks/Services/TaskService.cs @@ -0,0 +1,45 @@ +using Dal.Entities; +using Dal.Repositories.Interfaces; +using Dal.Repositories.Tasks; +using Logic.Tasks.Services.Interfaces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Logic.Tasks.Services; + +public class TaskService : ITaskService +{ + private readonly ITaskRepository _repo; + + public TaskService(ITaskRepository repo) + { + _repo = repo; + } + + public Task CreateTaskAsync(string? title, Guid userId, CancellationToken cancellationToken) + => _repo.CreateAsync(new TaskEntity + { + Id = Guid.NewGuid(), + Title = title, + CreatedByUserId = userId, + CreatedUtc = DateTimeOffset.UtcNow + }); + + public Task> GetAllTasksAsync(CancellationToken cancellationToken) + => _repo.GetAllAsync(); + + public Task GetTaskByIdAsync(Guid id, CancellationToken cancellationToken) + => _repo.GetByIdAsync(id); + + public Task SetTaskTitleAsync(Guid id, string title, CancellationToken cancellationToken) + => _repo.UpdateTitleAsync(id, title); + + public Task DeleteTaskByIdAsync(Guid id, CancellationToken cancellationToken) + => _repo.DeleteAsync(id); + + public Task DeleteAllTasksAsync(CancellationToken cancellationToken) + => _repo.DeleteAllAsync(); +}