diff --git a/src/Application/Common/Behaviours/AuthorizationBehaviour.cs b/src/Application/Common/Behaviours/AuthorizationBehaviour.cs index 2b0378f..30de73f 100644 --- a/src/Application/Common/Behaviours/AuthorizationBehaviour.cs +++ b/src/Application/Common/Behaviours/AuthorizationBehaviour.cs @@ -5,19 +5,12 @@ using Hutopy.Application.Common.Security; namespace Hutopy.Application.Common.Behaviours; -public class AuthorizationBehaviour : IPipelineBehavior where TRequest : notnull +public class AuthorizationBehaviour( + IUser user, + IIdentityService identityService) + : IPipelineBehavior + where TRequest : notnull { - private readonly IUser _user; - private readonly IIdentityService _identityService; - - public AuthorizationBehaviour( - IUser user, - IIdentityService identityService) - { - _user = user; - _identityService = identityService; - } - public async Task Handle(TRequest request, RequestHandlerDelegate next, CancellationToken cancellationToken) { var authorizeAttributes = request.GetType().GetCustomAttributes(); @@ -25,7 +18,7 @@ public class AuthorizationBehaviour : IPipelineBehavior : IPipelineBehavior : IPipelineBehavior a.Policy)) { - var authorized = await _identityService.AuthorizeAsync(_user.Id, policy); + var authorized = await identityService.AuthorizeAsync(user.Id, policy); if (!authorized) { diff --git a/src/Application/Common/Behaviours/LoggingBehaviour.cs b/src/Application/Common/Behaviours/LoggingBehaviour.cs index 70812ca..07814ca 100644 --- a/src/Application/Common/Behaviours/LoggingBehaviour.cs +++ b/src/Application/Common/Behaviours/LoggingBehaviour.cs @@ -4,28 +4,24 @@ using Microsoft.Extensions.Logging; namespace Hutopy.Application.Common.Behaviours; -public class LoggingBehaviour : IRequestPreProcessor where TRequest : notnull +public class LoggingBehaviour( + ILogger logger, + IUser user, + IIdentityService identityService) + : IRequestPreProcessor + where TRequest : notnull { - private readonly ILogger _logger; - private readonly IUser _user; - private readonly IIdentityService _identityService; - - public LoggingBehaviour(ILogger logger, IUser user, IIdentityService identityService) - { - _logger = logger; - _user = user; - _identityService = identityService; - } + private readonly ILogger _logger = logger; public async Task Process(TRequest request, CancellationToken cancellationToken) { var requestName = typeof(TRequest).Name; - var userId = _user.Id ?? string.Empty; + var userId = user.Id ?? string.Empty; string? userName = string.Empty; if (!string.IsNullOrEmpty(userId)) { - userName = await _identityService.GetUserNameAsync(userId); + userName = await identityService.GetUserNameAsync(userId); } _logger.LogInformation("Hutopy Request: {Name} {@UserId} {@UserName} {@Request}", diff --git a/src/Application/Common/Behaviours/PerformanceBehaviour.cs b/src/Application/Common/Behaviours/PerformanceBehaviour.cs index 64e9b55..ada438a 100644 --- a/src/Application/Common/Behaviours/PerformanceBehaviour.cs +++ b/src/Application/Common/Behaviours/PerformanceBehaviour.cs @@ -4,24 +4,14 @@ using Microsoft.Extensions.Logging; namespace Hutopy.Application.Common.Behaviours; -public class PerformanceBehaviour : IPipelineBehavior where TRequest : notnull +public class PerformanceBehaviour( + ILogger logger, + IUser user, + IIdentityService identityService) + : IPipelineBehavior + where TRequest : notnull { - private readonly Stopwatch _timer; - private readonly ILogger _logger; - private readonly IUser _user; - private readonly IIdentityService _identityService; - - public PerformanceBehaviour( - ILogger logger, - IUser user, - IIdentityService identityService) - { - _timer = new Stopwatch(); - - _logger = logger; - _user = user; - _identityService = identityService; - } + private readonly Stopwatch _timer = new(); public async Task Handle(TRequest request, RequestHandlerDelegate next, CancellationToken cancellationToken) { @@ -33,20 +23,16 @@ public class PerformanceBehaviour : IPipelineBehavior 500) - { - var requestName = typeof(TRequest).Name; - var userId = _user.Id ?? string.Empty; - var userName = string.Empty; + if (elapsedMilliseconds <= 500) return response; - if (!string.IsNullOrEmpty(userId)) - { - userName = await _identityService.GetUserNameAsync(userId); - } + var requestName = typeof(TRequest).Name; + var userId = user.Id ?? string.Empty; + var userName = string.Empty; - _logger.LogWarning("Hutopy Long Running Request: {Name} ({ElapsedMilliseconds} milliseconds) {@UserId} {@UserName} {@Request}", - requestName, elapsedMilliseconds, userId, userName, request); - } + if (!string.IsNullOrEmpty(userId)) userName = await identityService.GetUserNameAsync(userId); + + logger.LogWarning("Hutopy Long Running Request: {Name} ({ElapsedMilliseconds} milliseconds) {@UserId} {@UserName} {@Request}", + requestName, elapsedMilliseconds, userId, userName, request); return response; } diff --git a/src/Application/Common/Behaviours/UnhandledExceptionBehaviour.cs b/src/Application/Common/Behaviours/UnhandledExceptionBehaviour.cs index a79558a..28d2a94 100644 --- a/src/Application/Common/Behaviours/UnhandledExceptionBehaviour.cs +++ b/src/Application/Common/Behaviours/UnhandledExceptionBehaviour.cs @@ -2,15 +2,11 @@ namespace Hutopy.Application.Common.Behaviours; -public class UnhandledExceptionBehaviour : IPipelineBehavior where TRequest : notnull +public class UnhandledExceptionBehaviour( + ILogger logger) + : IPipelineBehavior + where TRequest : notnull { - private readonly ILogger _logger; - - public UnhandledExceptionBehaviour(ILogger logger) - { - _logger = logger; - } - public async Task Handle(TRequest request, RequestHandlerDelegate next, CancellationToken cancellationToken) { try @@ -21,7 +17,7 @@ public class UnhandledExceptionBehaviour : IPipelineBehavio { var requestName = typeof(TRequest).Name; - _logger.LogError(ex, "Hutopy Request: Unhandled Exception for Request {Name} {@Request}", requestName, request); + logger.LogError(ex, "Hutopy Request: Unhandled Exception for Request {Name} {@Request}", requestName, request); throw; } diff --git a/src/Application/Common/Behaviours/ValidationBehaviour.cs b/src/Application/Common/Behaviours/ValidationBehaviour.cs index 262fce7..a564099 100644 --- a/src/Application/Common/Behaviours/ValidationBehaviour.cs +++ b/src/Application/Common/Behaviours/ValidationBehaviour.cs @@ -2,34 +2,27 @@ namespace Hutopy.Application.Common.Behaviours; -public class ValidationBehaviour : IPipelineBehavior - where TRequest : notnull +public class ValidationBehaviour(IEnumerable> validators) + : IPipelineBehavior + where TRequest : notnull { - private readonly IEnumerable> _validators; - - public ValidationBehaviour(IEnumerable> validators) - { - _validators = validators; - } - public async Task Handle(TRequest request, RequestHandlerDelegate next, CancellationToken cancellationToken) { - if (_validators.Any()) - { - var context = new ValidationContext(request); + if (!validators.Any()) return await next(); - var validationResults = await Task.WhenAll( - _validators.Select(v => - v.ValidateAsync(context, cancellationToken))); + var context = new ValidationContext(request); - var failures = validationResults - .Where(r => r.Errors.Any()) - .SelectMany(r => r.Errors) - .ToList(); + var validationResults = await Task.WhenAll( + validators.Select(v => + v.ValidateAsync(context, cancellationToken))); - if (failures.Any()) - throw new ValidationException(failures); - } + var failures = validationResults + .Where(r => r.Errors.Any()) + .SelectMany(r => r.Errors) + .ToList(); + + if (failures.Count != 0) throw new ValidationException(failures); + return await next(); } } diff --git a/src/Application/Common/Exceptions/ValidationException.cs b/src/Application/Common/Exceptions/ValidationException.cs index 1570fbc..f167275 100644 --- a/src/Application/Common/Exceptions/ValidationException.cs +++ b/src/Application/Common/Exceptions/ValidationException.cs @@ -2,14 +2,9 @@ namespace Hutopy.Application.Common.Exceptions; -public class ValidationException : Exception +public class ValidationException() + : Exception("One or more validation failures have occurred.") { - public ValidationException() - : base("One or more validation failures have occurred.") - { - Errors = new Dictionary(); - } - public ValidationException(IEnumerable failures) : this() { @@ -18,5 +13,5 @@ public class ValidationException : Exception .ToDictionary(failureGroup => failureGroup.Key, failureGroup => failureGroup.ToArray()); } - public IDictionary Errors { get; } + public IDictionary Errors { get; } = new Dictionary(); } diff --git a/src/Application/Common/Models/PaginatedList.cs b/src/Application/Common/Models/PaginatedList.cs index 53636fa..e0a4e59 100644 --- a/src/Application/Common/Models/PaginatedList.cs +++ b/src/Application/Common/Models/PaginatedList.cs @@ -1,19 +1,15 @@ namespace Hutopy.Application.Common.Models; -public class PaginatedList +public class PaginatedList( + IReadOnlyCollection items, + int count, + int pageNumber, + int pageSize) { - public IReadOnlyCollection Items { get; } - public int PageNumber { get; } - public int TotalPages { get; } - public int TotalCount { get; } - - public PaginatedList(IReadOnlyCollection items, int count, int pageNumber, int pageSize) - { - PageNumber = pageNumber; - TotalPages = (int)Math.Ceiling(count / (double)pageSize); - TotalCount = count; - Items = items; - } + public IReadOnlyCollection Items { get; } = items; + public int PageNumber { get; } = pageNumber; + public int TotalPages { get; } = (int)Math.Ceiling(count / (double)pageSize); + public int TotalCount { get; } = count; public bool HasPreviousPage => PageNumber > 1; diff --git a/src/Application/Common/Models/Result.cs b/src/Application/Common/Models/Result.cs index f052240..f99bb27 100644 --- a/src/Application/Common/Models/Result.cs +++ b/src/Application/Common/Models/Result.cs @@ -1,16 +1,12 @@ namespace Hutopy.Application.Common.Models; -public class Result +public class Result( + bool succeeded, + IEnumerable errors) { - internal Result(bool succeeded, IEnumerable errors) - { - Succeeded = succeeded; - Errors = errors.ToArray(); - } + public bool Succeeded { get; init; } = succeeded; - public bool Succeeded { get; init; } - - public string[] Errors { get; init; } + public string[] Errors { get; init; } = errors.ToArray(); public static Result Success() { diff --git a/src/Application/Common/Security/AuthorizeAttribute.cs b/src/Application/Common/Security/AuthorizeAttribute.cs index 6a8a965..ad2e1e1 100644 --- a/src/Application/Common/Security/AuthorizeAttribute.cs +++ b/src/Application/Common/Security/AuthorizeAttribute.cs @@ -3,7 +3,7 @@ /// /// Specifies the class this attribute is applied to requires authorization. /// -[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] +[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] public class AuthorizeAttribute : Attribute { /// diff --git a/src/Application/DependencyInjection.cs b/src/Application/DependencyInjection.cs index 3ff3e1e..d65e206 100644 --- a/src/Application/DependencyInjection.cs +++ b/src/Application/DependencyInjection.cs @@ -1,6 +1,7 @@ using System.Reflection; +using Microsoft.Extensions.DependencyInjection; -namespace Microsoft.Extensions.DependencyInjection; +namespace Hutopy.Application; public static class DependencyInjection { diff --git a/src/Application/FutureCreators/Commands/CreateFutureCreator.cs b/src/Application/FutureCreators/Commands/CreateFutureCreator.cs index 54f4e70..d1f412e 100644 --- a/src/Application/FutureCreators/Commands/CreateFutureCreator.cs +++ b/src/Application/FutureCreators/Commands/CreateFutureCreator.cs @@ -3,7 +3,7 @@ using Hutopy.Domain.Entities; namespace Hutopy.Application.FutureCreators.Commands; -public record CreateFutureCreatorCommand : IRequest +public abstract record CreateFutureCreatorCommand : IRequest { public required string FirstName { get; init; } public required string LastName { get; init; } @@ -13,16 +13,10 @@ public record CreateFutureCreatorCommand : IRequest public required string ReasonToJoin { get; init; } } -public class CreateFuturCreatorCommandHandler : IRequestHandler +public class CreateFutureCreatorCommandHandler( + IApplicationDbContext context) + : IRequestHandler { - private readonly IApplicationDbContext _context; - - - public CreateFuturCreatorCommandHandler(IApplicationDbContext context) - { - _context = context; - } - public async Task Handle(CreateFutureCreatorCommand request, CancellationToken cancellationToken) { var entity = new FutureCreator @@ -35,9 +29,9 @@ public class CreateFuturCreatorCommandHandler : IRequestHandler +public abstract record CreateSessionCheckoutCommand : IRequest { public required int Price { get; init; } @@ -10,21 +10,16 @@ public record CreateSessionCheckoutCommand : IRequest } -public class CreateSessionCheckoutCommandHandler : IRequestHandler +public class CreateSessionCheckoutCommandHandler( + IApplicationDbContext context, + IStripeService stripeService) + : IRequestHandler { - private readonly IApplicationDbContext _context; - private readonly IStripeService _stripeService; - - - public CreateSessionCheckoutCommandHandler(IApplicationDbContext context, IStripeService stripeService) - { - _context = context; - _stripeService = stripeService; - } - + private readonly IApplicationDbContext _context = context; + public async Task Handle(CreateSessionCheckoutCommand request, CancellationToken cancellationToken) { - var stripeSecret = await _stripeService.CreateCheckoutSession(request.Price, request.Currency); + var stripeSecret = await stripeService.CreateCheckoutSession(request.Price, request.Currency); return stripeSecret; } diff --git a/src/Application/TodoItems/Commands/CreateTodoItem/CreateTodoItem.cs b/src/Application/TodoItems/Commands/CreateTodoItem/CreateTodoItem.cs index a560109..c4a448a 100644 --- a/src/Application/TodoItems/Commands/CreateTodoItem/CreateTodoItem.cs +++ b/src/Application/TodoItems/Commands/CreateTodoItem/CreateTodoItem.cs @@ -11,15 +11,10 @@ public record CreateTodoItemCommand : IRequest public string? Title { get; init; } } -public class CreateTodoItemCommandHandler : IRequestHandler +public class CreateTodoItemCommandHandler( + IApplicationDbContext context) + : IRequestHandler { - private readonly IApplicationDbContext _context; - - public CreateTodoItemCommandHandler(IApplicationDbContext context) - { - _context = context; - } - public async Task Handle(CreateTodoItemCommand request, CancellationToken cancellationToken) { var entity = new TodoItem @@ -31,9 +26,9 @@ public class CreateTodoItemCommandHandler : IRequestHandler +public class DeleteTodoItemCommandHandler( + IApplicationDbContext context) + : IRequestHandler { - private readonly IApplicationDbContext _context; - - public DeleteTodoItemCommandHandler(IApplicationDbContext context) - { - _context = context; - } - public async Task Handle(DeleteTodoItemCommand request, CancellationToken cancellationToken) { - var entity = await _context.TodoItems + var entity = await context.TodoItems .FindAsync(new object[] { request.Id }, cancellationToken); Guard.Against.NotFound(request.Id, entity); - _context.TodoItems.Remove(entity); + context.TodoItems.Remove(entity); entity.AddDomainEvent(new TodoItemDeletedEvent(entity)); - await _context.SaveChangesAsync(cancellationToken); + await context.SaveChangesAsync(cancellationToken); } } diff --git a/src/Application/TodoItems/Commands/UpdateTodoItem/UpdateTodoItem.cs b/src/Application/TodoItems/Commands/UpdateTodoItem/UpdateTodoItem.cs index 9699859..68ad4e5 100644 --- a/src/Application/TodoItems/Commands/UpdateTodoItem/UpdateTodoItem.cs +++ b/src/Application/TodoItems/Commands/UpdateTodoItem/UpdateTodoItem.cs @@ -11,18 +11,13 @@ public record UpdateTodoItemCommand : IRequest public bool Done { get; init; } } -public class UpdateTodoItemCommandHandler : IRequestHandler +public class UpdateTodoItemCommandHandler( + IApplicationDbContext context) + : IRequestHandler { - private readonly IApplicationDbContext _context; - - public UpdateTodoItemCommandHandler(IApplicationDbContext context) - { - _context = context; - } - public async Task Handle(UpdateTodoItemCommand request, CancellationToken cancellationToken) { - var entity = await _context.TodoItems + var entity = await context.TodoItems .FindAsync(new object[] { request.Id }, cancellationToken); Guard.Against.NotFound(request.Id, entity); @@ -30,6 +25,6 @@ public class UpdateTodoItemCommandHandler : IRequestHandler +public class UpdateTodoItemDetailCommandHandler( + IApplicationDbContext context) + : IRequestHandler { - private readonly IApplicationDbContext _context; - - public UpdateTodoItemDetailCommandHandler(IApplicationDbContext context) - { - _context = context; - } - public async Task Handle(UpdateTodoItemDetailCommand request, CancellationToken cancellationToken) { - var entity = await _context.TodoItems + var entity = await context.TodoItems .FindAsync(new object[] { request.Id }, cancellationToken); Guard.Against.NotFound(request.Id, entity); @@ -34,6 +29,6 @@ public class UpdateTodoItemDetailCommandHandler : IRequestHandler +public class TodoItemCompletedEventHandler( + ILogger logger) + : INotificationHandler { - private readonly ILogger _logger; - - public TodoItemCompletedEventHandler(ILogger logger) - { - _logger = logger; - } - public Task Handle(TodoItemCompletedEvent notification, CancellationToken cancellationToken) { - _logger.LogInformation("Hutopy Domain Event: {DomainEvent}", notification.GetType().Name); + logger.LogInformation("Hutopy Domain Event: {DomainEvent}", notification.GetType().Name); return Task.CompletedTask; } diff --git a/src/Application/TodoItems/EventHandlers/TodoItemCreatedEventHandler.cs b/src/Application/TodoItems/EventHandlers/TodoItemCreatedEventHandler.cs index 7e20348..8aba373 100644 --- a/src/Application/TodoItems/EventHandlers/TodoItemCreatedEventHandler.cs +++ b/src/Application/TodoItems/EventHandlers/TodoItemCreatedEventHandler.cs @@ -3,18 +3,13 @@ using Microsoft.Extensions.Logging; namespace Hutopy.Application.TodoItems.EventHandlers; -public class TodoItemCreatedEventHandler : INotificationHandler +public class TodoItemCreatedEventHandler( + ILogger logger) + : INotificationHandler { - private readonly ILogger _logger; - - public TodoItemCreatedEventHandler(ILogger logger) - { - _logger = logger; - } - public Task Handle(TodoItemCreatedEvent notification, CancellationToken cancellationToken) { - _logger.LogInformation("Hutopy Domain Event: {DomainEvent}", notification.GetType().Name); + logger.LogInformation("Hutopy Domain Event: {DomainEvent}", notification.GetType().Name); return Task.CompletedTask; } diff --git a/src/Application/TodoItems/Queries/GetTodoItemsWithPagination/GetTodoItemsWithPagination.cs b/src/Application/TodoItems/Queries/GetTodoItemsWithPagination/GetTodoItemsWithPagination.cs index a34f162..b0ece59 100644 --- a/src/Application/TodoItems/Queries/GetTodoItemsWithPagination/GetTodoItemsWithPagination.cs +++ b/src/Application/TodoItems/Queries/GetTodoItemsWithPagination/GetTodoItemsWithPagination.cs @@ -4,31 +4,25 @@ using Hutopy.Application.Common.Models; namespace Hutopy.Application.TodoItems.Queries.GetTodoItemsWithPagination; -public record GetTodoItemsWithPaginationQuery : IRequest> +public abstract record GetTodoItemsWithPaginationQuery : IRequest> { public int ListId { get; init; } public int PageNumber { get; init; } = 1; public int PageSize { get; init; } = 10; } -public class GetTodoItemsWithPaginationQueryHandler : IRequestHandler> +public class GetTodoItemsWithPaginationQueryHandler( + IApplicationDbContext context, + IMapper mapper) + : IRequestHandler> { - private readonly IApplicationDbContext _context; - private readonly IMapper _mapper; - - public GetTodoItemsWithPaginationQueryHandler(IApplicationDbContext context, IMapper mapper) - { - _context = context; - _mapper = mapper; - } - public async Task> Handle(GetTodoItemsWithPaginationQuery request, CancellationToken cancellationToken) { Console.WriteLine(request); - return await _context.TodoItems + return await context.TodoItems .Where(x => x.ListId == request.ListId) .OrderBy(x => x.Title) - .ProjectTo(_mapper.ConfigurationProvider) + .ProjectTo(mapper.ConfigurationProvider) .PaginatedListAsync(request.PageNumber, request.PageSize); } } diff --git a/src/Application/TodoLists/Commands/CreateTodoList/CreateTodoList.cs b/src/Application/TodoLists/Commands/CreateTodoList/CreateTodoList.cs index c557f94..cf95696 100644 --- a/src/Application/TodoLists/Commands/CreateTodoList/CreateTodoList.cs +++ b/src/Application/TodoLists/Commands/CreateTodoList/CreateTodoList.cs @@ -8,24 +8,17 @@ public record CreateTodoListCommand : IRequest public string? Title { get; init; } } -public class CreateTodoListCommandHandler : IRequestHandler +public class CreateTodoListCommandHandler( + IApplicationDbContext context) + : IRequestHandler { - private readonly IApplicationDbContext _context; - - public CreateTodoListCommandHandler(IApplicationDbContext context) - { - _context = context; - } - public async Task Handle(CreateTodoListCommand request, CancellationToken cancellationToken) { - var entity = new TodoList(); + var entity = new TodoList { Title = request.Title }; - entity.Title = request.Title; + context.TodoLists.Add(entity); - _context.TodoLists.Add(entity); - - await _context.SaveChangesAsync(cancellationToken); + await context.SaveChangesAsync(cancellationToken); return entity.Id; } diff --git a/src/Application/TodoLists/Commands/DeleteTodoList/DeleteTodoList.cs b/src/Application/TodoLists/Commands/DeleteTodoList/DeleteTodoList.cs index a5c3634..3339e8a 100644 --- a/src/Application/TodoLists/Commands/DeleteTodoList/DeleteTodoList.cs +++ b/src/Application/TodoLists/Commands/DeleteTodoList/DeleteTodoList.cs @@ -4,25 +4,20 @@ namespace Hutopy.Application.TodoLists.Commands.DeleteTodoList; public record DeleteTodoListCommand(int Id) : IRequest; -public class DeleteTodoListCommandHandler : IRequestHandler +public class DeleteTodoListCommandHandler( + IApplicationDbContext context) + : IRequestHandler { - private readonly IApplicationDbContext _context; - - public DeleteTodoListCommandHandler(IApplicationDbContext context) - { - _context = context; - } - public async Task Handle(DeleteTodoListCommand request, CancellationToken cancellationToken) { - var entity = await _context.TodoLists + var entity = await context.TodoLists .Where(l => l.Id == request.Id) .SingleOrDefaultAsync(cancellationToken); Guard.Against.NotFound(request.Id, entity); - _context.TodoLists.Remove(entity); + context.TodoLists.Remove(entity); - await _context.SaveChangesAsync(cancellationToken); + await context.SaveChangesAsync(cancellationToken); } } diff --git a/src/Application/TodoLists/Commands/PurgeTodoLists/PurgeTodoLists.cs b/src/Application/TodoLists/Commands/PurgeTodoLists/PurgeTodoLists.cs index 9778b6a..1e75661 100644 --- a/src/Application/TodoLists/Commands/PurgeTodoLists/PurgeTodoLists.cs +++ b/src/Application/TodoLists/Commands/PurgeTodoLists/PurgeTodoLists.cs @@ -8,19 +8,14 @@ namespace Hutopy.Application.TodoLists.Commands.PurgeTodoLists; [Authorize(Policy = Policies.CanPurge)] public record PurgeTodoListsCommand : IRequest; -public class PurgeTodoListsCommandHandler : IRequestHandler +public class PurgeTodoListsCommandHandler( + IApplicationDbContext context) + : IRequestHandler { - private readonly IApplicationDbContext _context; - - public PurgeTodoListsCommandHandler(IApplicationDbContext context) - { - _context = context; - } - public async Task Handle(PurgeTodoListsCommand request, CancellationToken cancellationToken) { - _context.TodoLists.RemoveRange(_context.TodoLists); + context.TodoLists.RemoveRange(context.TodoLists); - await _context.SaveChangesAsync(cancellationToken); + await context.SaveChangesAsync(cancellationToken); } } diff --git a/src/Application/TodoLists/Commands/UpdateTodoList/UpdateTodoList.cs b/src/Application/TodoLists/Commands/UpdateTodoList/UpdateTodoList.cs index 98b44e9..8418030 100644 --- a/src/Application/TodoLists/Commands/UpdateTodoList/UpdateTodoList.cs +++ b/src/Application/TodoLists/Commands/UpdateTodoList/UpdateTodoList.cs @@ -9,25 +9,20 @@ public record UpdateTodoListCommand : IRequest public string? Title { get; init; } } -public class UpdateTodoListCommandHandler : IRequestHandler +public class UpdateTodoListCommandHandler( + IApplicationDbContext context) + : IRequestHandler { - private readonly IApplicationDbContext _context; - - public UpdateTodoListCommandHandler(IApplicationDbContext context) - { - _context = context; - } - public async Task Handle(UpdateTodoListCommand request, CancellationToken cancellationToken) { - var entity = await _context.TodoLists + var entity = await context.TodoLists .FindAsync(new object[] { request.Id }, cancellationToken); Guard.Against.NotFound(request.Id, entity); entity.Title = request.Title; - await _context.SaveChangesAsync(cancellationToken); + await context.SaveChangesAsync(cancellationToken); } } diff --git a/src/Application/TodoLists/Commands/UpdateTodoList/UpdateTodoListCommandValidator.cs b/src/Application/TodoLists/Commands/UpdateTodoList/UpdateTodoListCommandValidator.cs index 2e7ef97..ba008d6 100644 --- a/src/Application/TodoLists/Commands/UpdateTodoList/UpdateTodoListCommandValidator.cs +++ b/src/Application/TodoLists/Commands/UpdateTodoList/UpdateTodoListCommandValidator.cs @@ -18,7 +18,7 @@ public class UpdateTodoListCommandValidator : AbstractValidator BeUniqueTitle(UpdateTodoListCommand model, string title, CancellationToken cancellationToken) + private async Task BeUniqueTitle(UpdateTodoListCommand model, string title, CancellationToken cancellationToken) { return await _context.TodoLists .Where(l => l.Id != model.Id) diff --git a/src/Application/TodoLists/Queries/GetTodos/GetTodos.cs b/src/Application/TodoLists/Queries/GetTodos/GetTodos.cs index cb44450..9d4d32f 100644 --- a/src/Application/TodoLists/Queries/GetTodos/GetTodos.cs +++ b/src/Application/TodoLists/Queries/GetTodos/GetTodos.cs @@ -8,17 +8,11 @@ namespace Hutopy.Application.TodoLists.Queries.GetTodos; [Authorize] public record GetTodosQuery : IRequest; -public class GetTodosQueryHandler : IRequestHandler +public class GetTodosQueryHandler( + IApplicationDbContext context, + IMapper mapper) + : IRequestHandler { - private readonly IApplicationDbContext _context; - private readonly IMapper _mapper; - - public GetTodosQueryHandler(IApplicationDbContext context, IMapper mapper) - { - _context = context; - _mapper = mapper; - } - public async Task Handle(GetTodosQuery request, CancellationToken cancellationToken) { return new TodosVm @@ -28,9 +22,9 @@ public class GetTodosQueryHandler : IRequestHandler .Select(p => new LookupDto { Id = (int)p, Title = p.ToString() }) .ToList(), - Lists = await _context.TodoLists + Lists = await context.TodoLists .AsNoTracking() - .ProjectTo(_mapper.ConfigurationProvider) + .ProjectTo(mapper.ConfigurationProvider) .OrderBy(t => t.Title) .ToListAsync(cancellationToken) }; diff --git a/src/Application/TodoLists/Queries/GetTodos/TodoListDto.cs b/src/Application/TodoLists/Queries/GetTodos/TodoListDto.cs index 6236f9a..c0a84dc 100644 --- a/src/Application/TodoLists/Queries/GetTodos/TodoListDto.cs +++ b/src/Application/TodoLists/Queries/GetTodos/TodoListDto.cs @@ -4,18 +4,13 @@ namespace Hutopy.Application.TodoLists.Queries.GetTodos; public class TodoListDto { - public TodoListDto() - { - Items = Array.Empty(); - } - public int Id { get; init; } public string? Title { get; init; } public string? Colour { get; init; } - public IReadOnlyCollection Items { get; init; } + public IReadOnlyCollection Items { get; init; } = Array.Empty(); private class Mapping : Profile { diff --git a/src/Domain/Common/BaseEntity.cs b/src/Domain/Common/BaseEntity.cs index 2ecc1fe..388a3ce 100644 --- a/src/Domain/Common/BaseEntity.cs +++ b/src/Domain/Common/BaseEntity.cs @@ -8,10 +8,10 @@ public abstract class BaseEntity // Using non-generic integer types for simplicity public int Id { get; set; } - private readonly List _domainEvents = new(); + private readonly List _domainEvents = []; [NotMapped] - public IReadOnlyCollection DomainEvents => _domainEvents.AsReadOnly(); + public IEnumerable DomainEvents => _domainEvents.AsReadOnly(); public void AddDomainEvent(BaseEvent domainEvent) { diff --git a/src/Domain/Common/ValueObject.cs b/src/Domain/Common/ValueObject.cs index e419f3e..6604643 100644 --- a/src/Domain/Common/ValueObject.cs +++ b/src/Domain/Common/ValueObject.cs @@ -3,7 +3,7 @@ // Learn more: https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/microservice-ddd-cqrs-patterns/implement-value-objects public abstract class ValueObject { - protected static bool EqualOperator(ValueObject left, ValueObject right) + private static bool EqualOperator(ValueObject left, ValueObject right) { if (left is null ^ right is null) { diff --git a/src/Domain/Events/TodoItemCompletedEvent.cs b/src/Domain/Events/TodoItemCompletedEvent.cs index b44c3ea..8d7cad1 100644 --- a/src/Domain/Events/TodoItemCompletedEvent.cs +++ b/src/Domain/Events/TodoItemCompletedEvent.cs @@ -1,11 +1,8 @@ namespace Hutopy.Domain.Events; -public class TodoItemCompletedEvent : BaseEvent +public class TodoItemCompletedEvent( + TodoItem item) + : BaseEvent { - public TodoItemCompletedEvent(TodoItem item) - { - Item = item; - } - - public TodoItem Item { get; } + public TodoItem Item { get; } = item; } diff --git a/src/Domain/Events/TodoItemCreatedEvent.cs b/src/Domain/Events/TodoItemCreatedEvent.cs index 35db47f..4f87e92 100644 --- a/src/Domain/Events/TodoItemCreatedEvent.cs +++ b/src/Domain/Events/TodoItemCreatedEvent.cs @@ -1,11 +1,8 @@ namespace Hutopy.Domain.Events; -public class TodoItemCreatedEvent : BaseEvent +public class TodoItemCreatedEvent( + TodoItem item) + : BaseEvent { - public TodoItemCreatedEvent(TodoItem item) - { - Item = item; - } - - public TodoItem Item { get; } + public TodoItem Item { get; } = item; } diff --git a/src/Domain/Events/TodoItemDeletedEvent.cs b/src/Domain/Events/TodoItemDeletedEvent.cs index d65711d..1340b00 100644 --- a/src/Domain/Events/TodoItemDeletedEvent.cs +++ b/src/Domain/Events/TodoItemDeletedEvent.cs @@ -1,11 +1,8 @@ namespace Hutopy.Domain.Events; -public class TodoItemDeletedEvent : BaseEvent +public class TodoItemDeletedEvent( + TodoItem item) + : BaseEvent { - public TodoItemDeletedEvent(TodoItem item) - { - Item = item; - } - - public TodoItem Item { get; } + public TodoItem Item { get; } = item; } diff --git a/src/Domain/Exceptions/UnsupportedColourException.cs b/src/Domain/Exceptions/UnsupportedColourException.cs index 3946c28..676bbc7 100644 --- a/src/Domain/Exceptions/UnsupportedColourException.cs +++ b/src/Domain/Exceptions/UnsupportedColourException.cs @@ -1,9 +1,4 @@ namespace Hutopy.Domain.Exceptions; -public class UnsupportedColourException : Exception -{ - public UnsupportedColourException(string code) - : base($"Colour \"{code}\" is unsupported.") - { - } -} +public class UnsupportedColourException( + string code) : Exception($"Colour \"{code}\" is unsupported."); diff --git a/src/Domain/ValueObjects/Colour.cs b/src/Domain/ValueObjects/Colour.cs index cf3d5ab..7bd2590 100644 --- a/src/Domain/ValueObjects/Colour.cs +++ b/src/Domain/ValueObjects/Colour.cs @@ -47,7 +47,7 @@ public class Colour(string code) : ValueObject return Code; } - protected static IEnumerable SupportedColours + private static IEnumerable SupportedColours { get { diff --git a/src/Infrastructure/Data/ApplicationDbContext.cs b/src/Infrastructure/Data/ApplicationDbContext.cs index 1a41916..e565b11 100644 --- a/src/Infrastructure/Data/ApplicationDbContext.cs +++ b/src/Infrastructure/Data/ApplicationDbContext.cs @@ -7,10 +7,10 @@ using Microsoft.EntityFrameworkCore; namespace Hutopy.Infrastructure.Data; -public class ApplicationDbContext : IdentityDbContext, IApplicationDbContext +public class ApplicationDbContext( + DbContextOptions options) + : IdentityDbContext(options), IApplicationDbContext { - public ApplicationDbContext(DbContextOptions options) : base(options) { } - public DbSet TodoLists => Set(); public DbSet TodoItems => Set(); diff --git a/src/Infrastructure/Data/ApplicationDbContextInitialiser.cs b/src/Infrastructure/Data/ApplicationDbContextInitializer.cs similarity index 50% rename from src/Infrastructure/Data/ApplicationDbContextInitialiser.cs rename to src/Infrastructure/Data/ApplicationDbContextInitializer.cs index eb7b336..b595c1e 100644 --- a/src/Infrastructure/Data/ApplicationDbContextInitialiser.cs +++ b/src/Infrastructure/Data/ApplicationDbContextInitializer.cs @@ -1,5 +1,4 @@ -using System.Runtime.InteropServices; -using Hutopy.Domain.Constants; +using Hutopy.Domain.Constants; using Hutopy.Domain.Entities; using Hutopy.Infrastructure.Identity; using Microsoft.AspNetCore.Builder; @@ -10,44 +9,35 @@ using Microsoft.Extensions.Logging; namespace Hutopy.Infrastructure.Data; -public static class InitialiserExtensions +public static class InitializerExtensions { public static async Task InitialiseDatabaseAsync(this WebApplication app) { using var scope = app.Services.CreateScope(); - var initialiser = scope.ServiceProvider.GetRequiredService(); + var initializer = scope.ServiceProvider.GetRequiredService(); - await initialiser.InitialiseAsync(); + await initializer.InitialiseAsync(); - await initialiser.SeedAsync(); + await initializer.SeedAsync(); } } -public class ApplicationDbContextInitialiser +public class ApplicationDbContextInitializer( + ILogger logger, + ApplicationDbContext context, + UserManager userManager, + RoleManager roleManager) { - private readonly ILogger _logger; - private readonly ApplicationDbContext _context; - private readonly UserManager _userManager; - private readonly RoleManager _roleManager; - - public ApplicationDbContextInitialiser(ILogger logger, ApplicationDbContext context, UserManager userManager, RoleManager roleManager) - { - _logger = logger; - _context = context; - _userManager = userManager; - _roleManager = roleManager; - } - public async Task InitialiseAsync() { try { - await _context.Database.MigrateAsync(); + await context.Database.MigrateAsync(); } catch (Exception ex) { - _logger.LogError(ex, "An error occurred while initialising the database."); + logger.LogError(ex, "An error occurred while initialising the database."); throw; } } @@ -60,38 +50,38 @@ public class ApplicationDbContextInitialiser } catch (Exception ex) { - _logger.LogError(ex, "An error occurred while seeding the database."); + logger.LogError(ex, "An error occurred while seeding the database."); throw; } } - public async Task TrySeedAsync() + private async Task TrySeedAsync() { // Default roles var administratorRole = new IdentityRole(Roles.Administrator); - if (_roleManager.Roles.All(r => r.Name != administratorRole.Name)) + if (roleManager.Roles.All(r => r.Name != administratorRole.Name)) { - await _roleManager.CreateAsync(administratorRole); + await roleManager.CreateAsync(administratorRole); } // Default users var administrator = new ApplicationUser { UserName = "administrator@localhost", Email = "administrator@localhost" }; - if (_userManager.Users.All(u => u.UserName != administrator.UserName)) + if (userManager.Users.All(u => u.UserName != administrator.UserName)) { - await _userManager.CreateAsync(administrator, "Administrator1!"); + await userManager.CreateAsync(administrator, "Administrator1!"); if (!string.IsNullOrWhiteSpace(administratorRole.Name)) { - await _userManager.AddToRolesAsync(administrator, new [] { administratorRole.Name }); + await userManager.AddToRolesAsync(administrator, new [] { administratorRole.Name }); } } // Default data // Seed, if necessary - if (!_context.TodoLists.Any()) + if (!context.TodoLists.Any()) { - _context.TodoLists.Add(new TodoList + context.TodoLists.Add(new TodoList { Title = "Todo List", Items = @@ -103,7 +93,7 @@ public class ApplicationDbContextInitialiser } }); - await _context.SaveChangesAsync(); + await context.SaveChangesAsync(); } } } diff --git a/src/Infrastructure/Data/Interceptors/AuditableEntityInterceptor.cs b/src/Infrastructure/Data/Interceptors/AuditableEntityInterceptor.cs index 9d4b202..f38d7b5 100644 --- a/src/Infrastructure/Data/Interceptors/AuditableEntityInterceptor.cs +++ b/src/Infrastructure/Data/Interceptors/AuditableEntityInterceptor.cs @@ -6,19 +6,10 @@ using Microsoft.EntityFrameworkCore.Diagnostics; namespace Hutopy.Infrastructure.Data.Interceptors; -public class AuditableEntityInterceptor : SaveChangesInterceptor +public class AuditableEntityInterceptor( + IUser user, + TimeProvider dateTime) : SaveChangesInterceptor { - private readonly IUser _user; - private readonly TimeProvider _dateTime; - - public AuditableEntityInterceptor( - IUser user, - TimeProvider dateTime) - { - _user = user; - _dateTime = dateTime; - } - public override InterceptionResult SavingChanges(DbContextEventData eventData, InterceptionResult result) { UpdateEntities(eventData.Context); @@ -41,13 +32,13 @@ public class AuditableEntityInterceptor : SaveChangesInterceptor { if (entry.State is EntityState.Added or EntityState.Modified || entry.HasChangedOwnedEntities()) { - var utcNow = _dateTime.GetUtcNow(); + var utcNow = dateTime.GetUtcNow(); if (entry.State == EntityState.Added) { - entry.Entity.CreatedBy = _user.Id; + entry.Entity.CreatedBy = user.Id; entry.Entity.Created = utcNow; } - entry.Entity.LastModifiedBy = _user.Id; + entry.Entity.LastModifiedBy = user.Id; entry.Entity.LastModified = utcNow; } } diff --git a/src/Infrastructure/Data/Interceptors/DispatchDomainEventsInterceptor.cs b/src/Infrastructure/Data/Interceptors/DispatchDomainEventsInterceptor.cs index 3664dd3..3123ee7 100644 --- a/src/Infrastructure/Data/Interceptors/DispatchDomainEventsInterceptor.cs +++ b/src/Infrastructure/Data/Interceptors/DispatchDomainEventsInterceptor.cs @@ -5,15 +5,10 @@ using Microsoft.EntityFrameworkCore.Diagnostics; namespace Hutopy.Infrastructure.Data.Interceptors; -public class DispatchDomainEventsInterceptor : SaveChangesInterceptor +public class DispatchDomainEventsInterceptor( + IPublisher mediator) + : SaveChangesInterceptor { - private readonly IMediator _mediator; - - public DispatchDomainEventsInterceptor(IMediator mediator) - { - _mediator = mediator; - } - public override InterceptionResult SavingChanges(DbContextEventData eventData, InterceptionResult result) { DispatchDomainEvents(eventData.Context).GetAwaiter().GetResult(); @@ -45,6 +40,6 @@ public class DispatchDomainEventsInterceptor : SaveChangesInterceptor entities.ToList().ForEach(e => e.ClearDomainEvents()); foreach (var domainEvent in domainEvents) - await _mediator.Publish(domainEvent); + await mediator.Publish(domainEvent); } } diff --git a/src/Infrastructure/DependencyInjection.cs b/src/Infrastructure/DependencyInjection.cs index 7481df3..0651486 100644 --- a/src/Infrastructure/DependencyInjection.cs +++ b/src/Infrastructure/DependencyInjection.cs @@ -8,8 +8,9 @@ using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; -namespace Microsoft.Extensions.DependencyInjection; +namespace Hutopy.Infrastructure; public static class DependencyInjection { @@ -34,7 +35,7 @@ public static class DependencyInjection services.AddScoped(provider => provider.GetRequiredService()); - services.AddScoped(); + services.AddScoped(); services.AddAuthentication() .AddBearerToken(IdentityConstants.BearerScheme); diff --git a/src/Infrastructure/Identity/IdentityService.cs b/src/Infrastructure/Identity/IdentityService.cs index 015100b..71a3886 100644 --- a/src/Infrastructure/Identity/IdentityService.cs +++ b/src/Infrastructure/Identity/IdentityService.cs @@ -5,25 +5,15 @@ using Microsoft.AspNetCore.Identity; namespace Hutopy.Infrastructure.Identity; -public class IdentityService : IIdentityService +public class IdentityService( + UserManager userManager, + IUserClaimsPrincipalFactory userClaimsPrincipalFactory, + IAuthorizationService authorizationService) + : IIdentityService { - private readonly UserManager _userManager; - private readonly IUserClaimsPrincipalFactory _userClaimsPrincipalFactory; - private readonly IAuthorizationService _authorizationService; - - public IdentityService( - UserManager userManager, - IUserClaimsPrincipalFactory userClaimsPrincipalFactory, - IAuthorizationService authorizationService) - { - _userManager = userManager; - _userClaimsPrincipalFactory = userClaimsPrincipalFactory; - _authorizationService = authorizationService; - } - public async Task GetUserNameAsync(string userId) { - var user = await _userManager.FindByIdAsync(userId); + var user = await userManager.FindByIdAsync(userId); return user?.UserName; } @@ -36,44 +26,44 @@ public class IdentityService : IIdentityService Email = userName, }; - var result = await _userManager.CreateAsync(user, password); + var result = await userManager.CreateAsync(user, password); return (result.ToApplicationResult(), user.Id); } public async Task IsInRoleAsync(string userId, string role) { - var user = await _userManager.FindByIdAsync(userId); + var user = await userManager.FindByIdAsync(userId); - return user != null && await _userManager.IsInRoleAsync(user, role); + return user != null && await userManager.IsInRoleAsync(user, role); } public async Task AuthorizeAsync(string userId, string policyName) { - var user = await _userManager.FindByIdAsync(userId); + var user = await userManager.FindByIdAsync(userId); if (user == null) { return false; } - var principal = await _userClaimsPrincipalFactory.CreateAsync(user); + var principal = await userClaimsPrincipalFactory.CreateAsync(user); - var result = await _authorizationService.AuthorizeAsync(principal, policyName); + var result = await authorizationService.AuthorizeAsync(principal, policyName); return result.Succeeded; } public async Task DeleteUserAsync(string userId) { - var user = await _userManager.FindByIdAsync(userId); + var user = await userManager.FindByIdAsync(userId); return user != null ? await DeleteUserAsync(user) : Result.Success(); } public async Task DeleteUserAsync(ApplicationUser user) { - var result = await _userManager.DeleteAsync(user); + var result = await userManager.DeleteAsync(user); return result.ToApplicationResult(); } diff --git a/src/Infrastructure/Stripe/StripeService.cs b/src/Infrastructure/Stripe/StripeService.cs index 3cfb7ff..f54fda4 100644 --- a/src/Infrastructure/Stripe/StripeService.cs +++ b/src/Infrastructure/Stripe/StripeService.cs @@ -16,22 +16,20 @@ public class StripeService : IStripeService { var options = new SessionCreateOptions { - LineItems = new List - { + LineItems = + [ new SessionLineItemOptions { - PriceData = new SessionLineItemPriceDataOptions - { - UnitAmount = price, - Currency = currency, - ProductData = new SessionLineItemPriceDataProductDataOptions + PriceData = new SessionLineItemPriceDataOptions { - Name = "Tip", + UnitAmount = price, + Currency = currency, + ProductData = new SessionLineItemPriceDataProductDataOptions { Name = "Tip", }, }, - }, - Quantity = 1, - }, - }, + Quantity = 1, + } + + ], Mode = "payment", UiMode = "embedded", ReturnUrl = $"http://localhost:5173/creatorfolio", diff --git a/src/Web/DependencyInjection.cs b/src/Web/DependencyInjection.cs index a7dbc86..f8ede38 100644 --- a/src/Web/DependencyInjection.cs +++ b/src/Web/DependencyInjection.cs @@ -3,11 +3,10 @@ using Hutopy.Application.Common.Interfaces; using Hutopy.Infrastructure.Data; using Hutopy.Web.Services; using Microsoft.AspNetCore.Mvc; - using NSwag; using NSwag.Generation.Processors.Security; -namespace Microsoft.Extensions.DependencyInjection; +namespace Hutopy.Web; public static class DependencyInjection { diff --git a/src/Web/Endpoints/JoinUs.cs b/src/Web/Endpoints/JoinUs.cs index d49265f..9cd917b 100644 --- a/src/Web/Endpoints/JoinUs.cs +++ b/src/Web/Endpoints/JoinUs.cs @@ -9,8 +9,8 @@ public class JoinUs : EndpointGroupBase app.MapGroup(this) .MapPost(CreateFutureCreator); } - - public Task CreateFutureCreator(ISender sender, CreateFutureCreatorCommand command) + + private static Task CreateFutureCreator(ISender sender, CreateFutureCreatorCommand command) { return sender.Send(command); } diff --git a/src/Web/Endpoints/Stripe.cs b/src/Web/Endpoints/Stripe.cs index c7753b0..b5c4a6a 100644 --- a/src/Web/Endpoints/Stripe.cs +++ b/src/Web/Endpoints/Stripe.cs @@ -10,7 +10,7 @@ public class Stripe : EndpointGroupBase .MapPost(CreateSessionCheckout); } - public Task CreateSessionCheckout(ISender sender, CreateSessionCheckoutCommand command) + private static Task CreateSessionCheckout(ISender sender, CreateSessionCheckoutCommand command) { return sender.Send(command); } diff --git a/src/Web/Endpoints/TodoItems.cs b/src/Web/Endpoints/TodoItems.cs index 7cb1fa4..cc62ff8 100644 --- a/src/Web/Endpoints/TodoItems.cs +++ b/src/Web/Endpoints/TodoItems.cs @@ -20,31 +20,31 @@ public class TodoItems : EndpointGroupBase .MapDelete(DeleteTodoItem, "{id}"); } - public Task> GetTodoItemsWithPagination(ISender sender, [AsParameters] GetTodoItemsWithPaginationQuery query) + private static Task> GetTodoItemsWithPagination(ISender sender, [AsParameters] GetTodoItemsWithPaginationQuery query) { return sender.Send(query); } - public Task CreateTodoItem(ISender sender, CreateTodoItemCommand command) + private static Task CreateTodoItem(ISender sender, CreateTodoItemCommand command) { return sender.Send(command); } - public async Task UpdateTodoItem(ISender sender, int id, UpdateTodoItemCommand command) + private static async Task UpdateTodoItem(ISender sender, int id, UpdateTodoItemCommand command) { if (id != command.Id) return Results.BadRequest(); await sender.Send(command); return Results.NoContent(); } - public async Task UpdateTodoItemDetail(ISender sender, int id, UpdateTodoItemDetailCommand command) + private static async Task UpdateTodoItemDetail(ISender sender, int id, UpdateTodoItemDetailCommand command) { if (id != command.Id) return Results.BadRequest(); await sender.Send(command); return Results.NoContent(); } - public async Task DeleteTodoItem(ISender sender, int id) + private static async Task DeleteTodoItem(ISender sender, int id) { await sender.Send(new DeleteTodoItemCommand(id)); return Results.NoContent(); diff --git a/src/Web/Endpoints/TodoLists.cs b/src/Web/Endpoints/TodoLists.cs index fafd341..a191421 100644 --- a/src/Web/Endpoints/TodoLists.cs +++ b/src/Web/Endpoints/TodoLists.cs @@ -17,24 +17,24 @@ public class TodoLists : EndpointGroupBase .MapDelete(DeleteTodoList, "{id}"); } - public Task GetTodoLists(ISender sender) + private static Task GetTodoLists(ISender sender) { - return sender.Send(new GetTodosQuery()); + return sender.Send(new GetTodosQuery()); } - public Task CreateTodoList(ISender sender, CreateTodoListCommand command) + private static Task CreateTodoList(ISender sender, CreateTodoListCommand command) { return sender.Send(command); } - public async Task UpdateTodoList(ISender sender, int id, UpdateTodoListCommand command) + private static async Task UpdateTodoList(ISender sender, int id, UpdateTodoListCommand command) { if (id != command.Id) return Results.BadRequest(); await sender.Send(command); return Results.NoContent(); } - public async Task DeleteTodoList(ISender sender, int id) + private static async Task DeleteTodoList(ISender sender, int id) { await sender.Send(new DeleteTodoListCommand(id)); return Results.NoContent(); diff --git a/src/Web/Endpoints/WeatherForecasts.cs b/src/Web/Endpoints/WeatherForecasts.cs index 8eef1fd..75f26c4 100644 --- a/src/Web/Endpoints/WeatherForecasts.cs +++ b/src/Web/Endpoints/WeatherForecasts.cs @@ -11,7 +11,7 @@ public class WeatherForecasts : EndpointGroupBase .MapGet(GetWeatherForecasts); } - public async Task> GetWeatherForecasts(ISender sender) + private static async Task> GetWeatherForecasts(ISender sender) { return await sender.Send(new GetWeatherForecastsQuery()); } diff --git a/src/Web/Infrastructure/CustomExceptionHandler.cs b/src/Web/Infrastructure/CustomExceptionHandler.cs index e49063b..a94d865 100644 --- a/src/Web/Infrastructure/CustomExceptionHandler.cs +++ b/src/Web/Infrastructure/CustomExceptionHandler.cs @@ -11,8 +11,8 @@ public class CustomExceptionHandler : IExceptionHandler public CustomExceptionHandler() { // Register known exception types and handlers. - _exceptionHandlers = new() - { + _exceptionHandlers = new Dictionary> + { { typeof(ValidationException), HandleValidationException }, { typeof(NotFoundException), HandleNotFoundException }, { typeof(UnauthorizedAccessException), HandleUnauthorizedAccessException }, @@ -24,16 +24,14 @@ public class CustomExceptionHandler : IExceptionHandler { var exceptionType = exception.GetType(); - if (_exceptionHandlers.ContainsKey(exceptionType)) - { - await _exceptionHandlers[exceptionType].Invoke(httpContext, exception); - return true; - } + if (!_exceptionHandlers.TryGetValue(exceptionType, out Func? value)) return false; + + await value.Invoke(httpContext, exception); + return true; - return false; } - private async Task HandleValidationException(HttpContext httpContext, Exception ex) + private static async Task HandleValidationException(HttpContext httpContext, Exception ex) { var exception = (ValidationException)ex; @@ -46,7 +44,7 @@ public class CustomExceptionHandler : IExceptionHandler }); } - private async Task HandleNotFoundException(HttpContext httpContext, Exception ex) + private static async Task HandleNotFoundException(HttpContext httpContext, Exception ex) { var exception = (NotFoundException)ex; @@ -61,7 +59,7 @@ public class CustomExceptionHandler : IExceptionHandler }); } - private async Task HandleUnauthorizedAccessException(HttpContext httpContext, Exception ex) + private static async Task HandleUnauthorizedAccessException(HttpContext httpContext, Exception ex) { httpContext.Response.StatusCode = StatusCodes.Status401Unauthorized; @@ -73,7 +71,7 @@ public class CustomExceptionHandler : IExceptionHandler }); } - private async Task HandleForbiddenAccessException(HttpContext httpContext, Exception ex) + private static async Task HandleForbiddenAccessException(HttpContext httpContext, Exception ex) { httpContext.Response.StatusCode = StatusCodes.Status403Forbidden; diff --git a/src/Web/Infrastructure/MethodInfoExtensions.cs b/src/Web/Infrastructure/MethodInfoExtensions.cs index d526cb4..342edc4 100644 --- a/src/Web/Infrastructure/MethodInfoExtensions.cs +++ b/src/Web/Infrastructure/MethodInfoExtensions.cs @@ -4,7 +4,7 @@ namespace Hutopy.Web.Infrastructure; public static class MethodInfoExtensions { - public static bool IsAnonymous(this MethodInfo method) + private static bool IsAnonymous(this MethodInfo method) { var invalidChars = new[] { '<', '>' }; return method.Name.Any(invalidChars.Contains); @@ -15,4 +15,4 @@ public static class MethodInfoExtensions if (input.Method.IsAnonymous()) throw new ArgumentException("The endpoint name must be specified when using anonymous handlers."); } -} \ No newline at end of file +} diff --git a/src/Web/Program.cs b/src/Web/Program.cs index 89e64ee..85dbf27 100644 --- a/src/Web/Program.cs +++ b/src/Web/Program.cs @@ -1,4 +1,7 @@ +using Hutopy.Application; +using Hutopy.Infrastructure; using Hutopy.Infrastructure.Data; +using Hutopy.Web; var builder = WebApplication.CreateBuilder(args); @@ -61,4 +64,4 @@ app.MapEndpoints(); app.Run(); -public partial class Program { } +public abstract partial class Program { } diff --git a/src/Web/Services/CurrentUser.cs b/src/Web/Services/CurrentUser.cs index 45d3365..50a502a 100644 --- a/src/Web/Services/CurrentUser.cs +++ b/src/Web/Services/CurrentUser.cs @@ -4,14 +4,9 @@ using Hutopy.Application.Common.Interfaces; namespace Hutopy.Web.Services; -public class CurrentUser : IUser +public class CurrentUser( + IHttpContextAccessor httpContextAccessor) + : IUser { - private readonly IHttpContextAccessor _httpContextAccessor; - - public CurrentUser(IHttpContextAccessor httpContextAccessor) - { - _httpContextAccessor = httpContextAccessor; - } - - public string? Id => _httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier); + public string? Id => httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier); }