Skip to content

Commit

Permalink
Primary Constructors
Browse files Browse the repository at this point in the history
  • Loading branch information
isaacOjeda committed Feb 3, 2024
1 parent de1da2a commit c275840
Show file tree
Hide file tree
Showing 11 changed files with 48 additions and 124 deletions.
10 changes: 3 additions & 7 deletions src/Application/Common/Behaviours/LoggingBehaviour.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,10 @@

namespace MinimalApiArchitecture.Application.Common.Behaviours;

public class LoggingBehaviour<TRequest> : IRequestPreProcessor<TRequest> where TRequest : notnull
public class LoggingBehaviour<TRequest>(ILogger<TRequest> logger) : IRequestPreProcessor<TRequest>
where TRequest : notnull
{
private readonly ILogger _logger;

public LoggingBehaviour(ILogger<TRequest> logger)
{
_logger = logger;
}
private readonly ILogger _logger = logger;

public Task Process(TRequest request, CancellationToken cancellationToken)
{
Expand Down
22 changes: 8 additions & 14 deletions src/Application/Common/Behaviours/TransactionBehaviour.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,27 @@

namespace MinimalApiArchitecture.Application.Common.Behaviours
{
public class TransactionBehaviour<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
public class TransactionBehaviour<TRequest, TResponse>(
ApiDbContext context,
ILogger<TransactionBehaviour<TRequest, TResponse>> logger)
: IPipelineBehavior<TRequest, TResponse>
where TRequest : IRequest<TResponse>
{
private readonly ApiDbContext _context;
private readonly ILogger<TransactionBehaviour<TRequest, TResponse>> _logger;

public TransactionBehaviour(ApiDbContext context, ILogger<TransactionBehaviour<TRequest, TResponse>> logger)
{
_context = context;
_logger = logger;
}

public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
{
try
{
await _context.BeginTransactionAsync();
await context.BeginTransactionAsync();
var response = await next();
await _context.CommitTransactionAsync();
await context.CommitTransactionAsync();

return response;
}
catch (Exception)
{
_logger.LogError("Request failed: Rolling back all the changes made to the Context");
logger.LogError("Request failed: Rolling back all the changes made to the Context");

await _context.RollbackTransaction();
await context.RollbackTransaction();
throw;
}
}
Expand Down
12 changes: 3 additions & 9 deletions src/Application/Domain/Entities/Category.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
namespace MinimalApiArchitecture.Application.Domain.Entities;

public class Category
public class Category(int categoryId, string name)
{
public Category(int categoryId, string name)
{
CategoryId = categoryId;
Name = name;
}

public int CategoryId { get; set; }
public string Name { get; set; }
public int CategoryId { get; set; } = categoryId;
public string Name { get; set; } = name;

public ICollection<Product> Products { get; set; } =
new HashSet<Product>();
Expand Down
22 changes: 7 additions & 15 deletions src/Application/Domain/Entities/Product.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,14 @@

namespace MinimalApiArchitecture.Application.Domain.Entities;

public class Product : IHasDomainEvent
public class Product(int productId, string name, string description, double price, int categoryId)
: IHasDomainEvent
{
public Product(int productId, string name, string description, double price, int categoryId)
{
ProductId = productId;
Name = name;
Description = description;
Price = price;
CategoryId = categoryId;
}

public int ProductId { get; set; }
public string Name { get; private set; }
public string Description { get; private set; }
public double Price { get; private set; }
public int CategoryId { get; private set; }
public int ProductId { get; set; } = productId;
public string Name { get; private set; } = name;
public string Description { get; private set; } = description;
public double Price { get; private set; } = price;
public int CategoryId { get; private set; } = categoryId;
public Category? Category { get; private set; }

public List<DomainEvent> DomainEvents { get; set; } = new List<DomainEvent>();
Expand Down
9 changes: 2 additions & 7 deletions src/Application/Domain/Events/ProductUpdatePriceEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,8 @@

namespace MinimalApiArchitecture.Application.Domain.Events
{
public class ProductUpdatePriceEvent : DomainEvent
public class ProductUpdatePriceEvent(Product product) : DomainEvent
{
public ProductUpdatePriceEvent(Product product)
{
Product = product;
}

public Product Product { get; set; }
public Product Product { get; set; } = product;
}
}
14 changes: 3 additions & 11 deletions src/Application/Features/Categories/Queries/GetCategories.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,11 @@ public class GetCategoriesQuery : IRequest<List<GetCategoriesResponse>>

}

public class GetCategoriesHandler : IRequestHandler<GetCategoriesQuery, List<GetCategoriesResponse>>
public class GetCategoriesHandler(ApiDbContext context, IMapper mapper)
: IRequestHandler<GetCategoriesQuery, List<GetCategoriesResponse>>
{
private readonly ApiDbContext _context;
private readonly IMapper _mapper;

public GetCategoriesHandler(ApiDbContext context, IMapper mapper)
{
_context = context;
_mapper = mapper;
}

public Task<List<GetCategoriesResponse>> Handle(GetCategoriesQuery request, CancellationToken cancellationToken) =>
_context.Categories.ProjectTo<GetCategoriesResponse>(_mapper.ConfigurationProvider).ToListAsync();
context.Categories.ProjectTo<GetCategoriesResponse>(mapper.ConfigurationProvider).ToListAsync();
}

public class GetCategoriesResponse
Expand Down
18 changes: 5 additions & 13 deletions src/Application/Features/Products/Commands/CreateProduct.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,30 +32,22 @@ public class CreateProductCommand : IRequest<IResult>
public int CategoryId { get; set; }
}

public class CreateProductHandler : IRequestHandler<CreateProductCommand, IResult>
public class CreateProductHandler(ApiDbContext context, IValidator<CreateProductCommand> validator)
: IRequestHandler<CreateProductCommand, IResult>
{
private readonly ApiDbContext _context;
private readonly IValidator<CreateProductCommand> _validator;

public CreateProductHandler(ApiDbContext context, IValidator<CreateProductCommand> validator)
{
_context = context;
_validator = validator;
}

public async Task<IResult> Handle(CreateProductCommand request, CancellationToken cancellationToken)
{
var result = _validator.Validate(request);
var result = validator.Validate(request);
if (!result.IsValid)
{
return Results.ValidationProblem(result.GetValidationProblems());
}

var newProduct = new Product(0, request.Name, request.Description, request.Price, request.CategoryId);

_context.Products.Add(newProduct);
context.Products.Add(newProduct);

await _context.SaveChangesAsync();
await context.SaveChangesAsync();

return Results.Created($"api/products/{newProduct.ProductId}", null);
}
Expand Down
21 changes: 6 additions & 15 deletions src/Application/Features/Products/Commands/DeleteProduct.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,34 +22,25 @@ public void AddRoutes(IEndpointRouteBuilder app)
.Produces(StatusCodes.Status404NotFound);
}

public class DeleteProductCommand : IRequest<IResult>
public class DeleteProductCommand(int productId) : IRequest<IResult>
{
public DeleteProductCommand(int productId) => ProductId = productId;

public int ProductId { get; set; }
public int ProductId { get; set; } = productId;
}

public class DeleteProductHandler : IRequestHandler<DeleteProductCommand, IResult>
public class DeleteProductHandler(ApiDbContext context) : IRequestHandler<DeleteProductCommand, IResult>
{
private readonly ApiDbContext _context;

public DeleteProductHandler(ApiDbContext context)
{
_context = context;
}

public async Task<IResult> Handle(DeleteProductCommand request, CancellationToken cancellationToken)
{
var product = await _context.Products.FindAsync(request.ProductId);
var product = await context.Products.FindAsync(request.ProductId);

if (product is null)
{
return Results.NotFound();
}

_context.Products.Remove(product);
context.Products.Remove(product);

await _context.SaveChangesAsync();
await context.SaveChangesAsync();

return Results.Ok();
}
Expand Down
18 changes: 5 additions & 13 deletions src/Application/Features/Products/Commands/UpdateProduct.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,26 +33,18 @@ public class UpdateProductCommand : IRequest<IResult>
public int CategoryId { get; set; }
}

public class UpdateProductHandler : IRequestHandler<UpdateProductCommand, IResult>
public class UpdateProductHandler(ApiDbContext context, IValidator<UpdateProductCommand> validator)
: IRequestHandler<UpdateProductCommand, IResult>
{
private readonly ApiDbContext _context;
private readonly IValidator<UpdateProductCommand> _validator;

public UpdateProductHandler(ApiDbContext context, IValidator<UpdateProductCommand> validator)
{
_context = context;
_validator = validator;
}

public async Task<IResult> Handle(UpdateProductCommand request, CancellationToken cancellationToken)
{
var result = _validator.Validate(request);
var result = validator.Validate(request);
if (!result.IsValid)
{
return Results.ValidationProblem(result.GetValidationProblems());
}

var product = await _context.Products.FindAsync(request.ProductId);
var product = await context.Products.FindAsync(request.ProductId);

if (product is null)
{
Expand All @@ -61,7 +53,7 @@ public async Task<IResult> Handle(UpdateProductCommand request, CancellationToke

product.UpdateInfo(request);

await _context.SaveChangesAsync();
await context.SaveChangesAsync();

return Results.Ok();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,12 @@

namespace MinimalApiArchitecture.Application.Features.Products.EventHandlers
{
public class PriceChangedEventHandler : INotificationHandler<ProductUpdatePriceEvent>
public class PriceChangedEventHandler(ILogger<PriceChangedEventHandler> logger)
: INotificationHandler<ProductUpdatePriceEvent>
{
private readonly ILogger<PriceChangedEventHandler> _logger;

public PriceChangedEventHandler(ILogger<PriceChangedEventHandler> logger)
{
_logger = logger;
}

public Task Handle(ProductUpdatePriceEvent notification, CancellationToken cancellationToken)
{
_logger.LogWarning("Minimal APIs Domain Event: {DomainEvent}", notification.GetType().Name);
logger.LogWarning("Minimal APIs Domain Event: {DomainEvent}", notification.GetType().Name);

return Task.CompletedTask;
}
Expand Down
14 changes: 3 additions & 11 deletions src/Application/Features/Products/Queries/GetProducts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,11 @@ public class GetProductsQuery : IRequest<List<GetProductsResponse>>

}

public class GetProductsHandler : IRequestHandler<GetProductsQuery, List<GetProductsResponse>>
public class GetProductsHandler(ApiDbContext context, IMapper mapper)
: IRequestHandler<GetProductsQuery, List<GetProductsResponse>>
{
private readonly ApiDbContext _context;
private readonly IMapper _mapper;

public GetProductsHandler(ApiDbContext context, IMapper mapper)
{
_context = context;
_mapper = mapper;
}

public Task<List<GetProductsResponse>> Handle(GetProductsQuery request, CancellationToken cancellationToken) =>
_context.Products.ProjectTo<GetProductsResponse>(_mapper.ConfigurationProvider).ToListAsync();
context.Products.ProjectTo<GetProductsResponse>(mapper.ConfigurationProvider).ToListAsync();
}

public class GetProductsMappingProfile : Profile
Expand Down

0 comments on commit c275840

Please sign in to comment.