Skip to content

Commit

Permalink
feat(automapper): added AutoMapper profiles to commands/queries and c…
Browse files Browse the repository at this point in the history
…orresponding tests

fix(circulardependencies,packagereference): added frameworkreference instead of packagereference for aspnetcore.app to avoid warning and fixed automapper circular dependencies related to the use of entity instead of dto

chore(husky): added the actual pre-commit hook to run csharpier on each
  • Loading branch information
mezdelex committed Nov 13, 2024
1 parent db36fc8 commit 110c4c4
Show file tree
Hide file tree
Showing 30 changed files with 144 additions and 93 deletions.
22 changes: 22 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

## husky task runner examples -------------------
## Note : for local installation use 'dotnet' prefix. e.g. 'dotnet husky'

## run all tasks
#husky run

### run all tasks with group: 'group-name'
#husky run --group group-name

## run task with name: 'task-name'
#husky run --name task-name

## pass hook arguments to task
#husky run --args "$1" "$2"

## or put your custom commands -------------------
#echo 'Husky.Net is awesome!'

dotnet husky run
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# .NET 8 Clean Architecture Template

.NET 8 Clean Architecture + DDD + CQRS + Specifications + Domain Events + Testing + Identity + Redis
.NET 8 Clean Architecture + DDD + CQRS + Specifications + AutoMapper + Domain Events + Testing + Identity + Redis

## Docker

Expand Down
3 changes: 3 additions & 0 deletions src/Application/Application.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
Expand All @@ -7,6 +8,7 @@

<ItemGroup>
<PackageReference Include="ardalis.specification" Version="8.0.0" />
<PackageReference Include="automapper" Version="13.0.1" />
<PackageReference Include="fluentvalidation.dependencyinjectionextensions" Version="11.9.2" />
<PackageReference Include="masstransit" Version="8.2.3" />
<PackageReference Include="mediatr" Version="12.4.0" />
Expand All @@ -16,4 +18,5 @@
<ItemGroup>
<ProjectReference Include="..\Domain\Domain.csproj" />
</ItemGroup>

</Project>
1 change: 1 addition & 0 deletions src/Application/Extensions/ApplicationExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ public static void AddApplicationDependencies(this IServiceCollection services)

services.AddMediatR(configuration => configuration.RegisterServicesFromAssembly(assembly));
services.AddValidatorsFromAssembly(assembly);
services.AddAutoMapper(assembly);
}
}
16 changes: 5 additions & 11 deletions src/Application/Features/Commands/PatchCategoryCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,21 @@ public sealed record PatchCategoryCommand(Guid Id, string Name, string Descripti
public sealed class PatchCategoryCommandHandler : IRequestHandler<PatchCategoryCommand>
{
private readonly IValidator<PatchCategoryCommand> _validator;
private readonly IMapper _mapper;
private readonly ICategoriesRepository _repository;
private readonly IUnitOfWork _uow;
private readonly IEventBus _eventBus;

public PatchCategoryCommandHandler(
IValidator<PatchCategoryCommand> validator,
IMapper mapper,
ICategoriesRepository repository,
IUnitOfWork uow,
IEventBus eventBus
)
{
_validator = validator;
_mapper = mapper;
_repository = repository;
_uow = uow;
_eventBus = eventBus;
Expand All @@ -28,21 +31,12 @@ public async Task Handle(PatchCategoryCommand request, CancellationToken cancell
if (!results.IsValid)
throw new ValidationException(results.ToString().Replace("\r\n", " "));

var categoryToPatch = new Category
{
Id = request.Id,
Name = request.Name,
Description = request.Description,
};
var categoryToPatch = _mapper.Map<Category>(request);

await _repository.PatchAsync(categoryToPatch, cancellationToken);
await _uow.SaveChangesAsync(cancellationToken);
await _eventBus.PublishAsync(
new PatchedCategoryEvent(
categoryToPatch.Id,
categoryToPatch.Name,
categoryToPatch.Description
),
_mapper.Map<PatchedCategoryEvent>(categoryToPatch),
cancellationToken
);
}
Expand Down
20 changes: 5 additions & 15 deletions src/Application/Features/Commands/PatchExpenseCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,21 @@ Guid CategoryId
public sealed class PatchExpenseCommandHandler : IRequestHandler<PatchExpenseCommand>
{
private readonly IValidator<PatchExpenseCommand> _validator;
private readonly IMapper _mapper;
private readonly IExpensesRepository _repository;
private readonly IUnitOfWork _uow;
private readonly IEventBus _eventBus;

public PatchExpenseCommandHandler(
IValidator<PatchExpenseCommand> validator,
IMapper mapper,
IExpensesRepository repository,
IUnitOfWork uow,
IEventBus eventBus
)
{
_validator = validator;
_mapper = mapper;
_repository = repository;
_uow = uow;
_eventBus = eventBus;
Expand All @@ -34,25 +37,12 @@ public async Task Handle(PatchExpenseCommand request, CancellationToken cancella
if (!results.IsValid)
throw new ValidationException(results.ToString().Replace("\r\n", " "));

var expenseToPatch = new Expense
{
Id = request.Id,
Name = request.Name,
Description = request.Description,
Value = request.Value,
CategoryId = request.CategoryId,
};
var expenseToPatch = _mapper.Map<Expense>(request);

await _repository.PatchAsync(expenseToPatch, cancellationToken);
await _uow.SaveChangesAsync(cancellationToken);
await _eventBus.PublishAsync(
new PatchedExpenseEvent(
expenseToPatch.Id,
expenseToPatch.Name,
expenseToPatch.Description,
expenseToPatch.Value,
expenseToPatch.CategoryId
),
_mapper.Map<PatchedExpenseEvent>(expenseToPatch),
cancellationToken
);
}
Expand Down
16 changes: 5 additions & 11 deletions src/Application/Features/Commands/PostCategoryCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,21 @@ public sealed record PostCategoryCommand(string Name, string Description) : IReq
public sealed class PostCategoryCommandHandler : IRequestHandler<PostCategoryCommand>
{
private readonly IValidator<PostCategoryCommand> _validator;
private readonly IMapper _mapper;
private readonly ICategoriesRepository _repository;
private readonly IUnitOfWork _uow;
private readonly IEventBus _eventBus;

public PostCategoryCommandHandler(
IValidator<PostCategoryCommand> validator,
IMapper mapper,
ICategoriesRepository repository,
IUnitOfWork uow,
IEventBus eventBus
)
{
_validator = validator;
_mapper = mapper;
_repository = repository;
_uow = uow;
_eventBus = eventBus;
Expand All @@ -28,21 +31,12 @@ public async Task Handle(PostCategoryCommand request, CancellationToken cancella
if (!results.IsValid)
throw new ValidationException(results.ToString().Replace("\r\n", " "));

var categoryToPost = new Category
{
Id = Guid.NewGuid(),
Name = request.Name,
Description = request.Description,
};
var categoryToPost = _mapper.Map<Category>(request);

await _repository.PostAsync(categoryToPost, cancellationToken);
await _uow.SaveChangesAsync(cancellationToken);
await _eventBus.PublishAsync(
new PostedCategoryEvent(
categoryToPost.Id,
categoryToPost.Name,
categoryToPost.Description
),
_mapper.Map<PostedCategoryEvent>(categoryToPost),
cancellationToken
);
}
Expand Down
20 changes: 5 additions & 15 deletions src/Application/Features/Commands/PostExpenseCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,21 @@ Guid CategoryId
public sealed class PostExpenseCommandHandler : IRequestHandler<PostExpenseCommand>
{
private readonly IValidator<PostExpenseCommand> _validator;
private readonly IMapper _mapper;
private readonly IExpensesRepository _repository;
private readonly IUnitOfWork _uow;
private readonly IEventBus _eventBus;

public PostExpenseCommandHandler(
IValidator<PostExpenseCommand> validator,
IMapper mapper,
IExpensesRepository repository,
IUnitOfWork uow,
IEventBus eventBus
)
{
_validator = validator;
_mapper = mapper;
_repository = repository;
_uow = uow;
_eventBus = eventBus;
Expand All @@ -33,25 +36,12 @@ public async Task Handle(PostExpenseCommand request, CancellationToken cancellat
if (!results.IsValid)
throw new ValidationException(results.ToString().Replace("\r\n", " "));

var expenseToPost = new Expense
{
Id = Guid.NewGuid(),
Name = request.Name,
Description = request.Description,
Value = request.Value,
CategoryId = request.CategoryId,
};
var expenseToPost = _mapper.Map<Expense>(request);

await _repository.PostAsync(expenseToPost, cancellationToken);
await _uow.SaveChangesAsync(cancellationToken);
await _eventBus.PublishAsync(
new PostedExpenseEvent(
expenseToPost.Id,
expenseToPost.Name,
expenseToPost.Description,
expenseToPost.Value,
expenseToPost.CategoryId
),
_mapper.Map<PostedExpenseEvent>(expenseToPost),
cancellationToken
);
}
Expand Down
5 changes: 4 additions & 1 deletion src/Application/Features/Queries/GetAllCategoriesQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,17 @@ public sealed class GetAllCategoriesQueryHandler
: IRequestHandler<GetAllCategoriesQuery, PagedList<CategoryDTO>>
{
private readonly ICategoriesRepository _repository;
private readonly IMapper _mapper;
private readonly IRedisCache _redisCache;

public GetAllCategoriesQueryHandler(
ICategoriesRepository repository,
IMapper mapper,
IRedisCache redisCache
)
{
_repository = repository;
_mapper = mapper;
_redisCache = redisCache;
}

Expand All @@ -39,7 +42,7 @@ CancellationToken cancellationToken
containedWord: request.ContainedWord
)
)
.Select(c => new CategoryDTO(c.Id, c.Name, c.Description, c.Expenses))
.Select(c => _mapper.Map<CategoryDTO>(c))
.ToPagedListAsync(request.Page, request.PageSize, cancellationToken);

await _redisCache.SetCachedData<PagedList<CategoryDTO>>(
Expand Down
10 changes: 8 additions & 2 deletions src/Application/Features/Queries/GetAllExpensesQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,17 @@ public sealed class GetAllExpensesQueryHandler
: IRequestHandler<GetAllExpensesQuery, PagedList<ExpenseDTO>>
{
private readonly IExpensesRepository _repository;
private readonly IMapper _mapper;
private readonly IRedisCache _redisCache;

public GetAllExpensesQueryHandler(IExpensesRepository repository, IRedisCache redisCache)
public GetAllExpensesQueryHandler(
IExpensesRepository repository,
IMapper mapper,
IRedisCache redisCache
)
{
_repository = repository;
_mapper = mapper;
_redisCache = redisCache;
}

Expand All @@ -38,7 +44,7 @@ CancellationToken cancellationToken
categoryId: request.CategoryId
)
)
.Select(x => new ExpenseDTO(x.Id, x.Name, x.Description, x.Value, x.CategoryId))
.Select(e => _mapper.Map<ExpenseDTO>(e))
.ToPagedListAsync(request.Page, request.PageSize, cancellationToken);

await _redisCache.SetCachedData<PagedList<ExpenseDTO>>(
Expand Down
11 changes: 4 additions & 7 deletions src/Application/Features/Queries/GetCategoryQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ public sealed record GetCategoryQuery(Guid Id) : IRequest<CategoryDTO>
public class GetCategoryQueryHandler : IRequestHandler<GetCategoryQuery, CategoryDTO>
{
private readonly ICategoriesRepository _repository;
private readonly IMapper _mapper;

public GetCategoryQueryHandler(ICategoriesRepository repository)
public GetCategoryQueryHandler(ICategoriesRepository repository, IMapper mapper)
{
_repository = repository;
_mapper = mapper;
}

public async Task<CategoryDTO> Handle(
Expand All @@ -22,12 +24,7 @@ await _repository.GetBySpecAsync(
cancellationToken
) ?? throw new NotFoundException(request.Id);

return new CategoryDTO(
category.Id,
category.Name,
category.Description,
category.Expenses
);
return _mapper.Map<CategoryDTO>(category);
}
}

Expand Down
12 changes: 4 additions & 8 deletions src/Application/Features/Queries/GetExpenseQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ public sealed record GetExpenseQuery(Guid Id) : IRequest<ExpenseDTO>
public sealed class GetExpenseQueryHandler : IRequestHandler<GetExpenseQuery, ExpenseDTO>
{
private readonly IExpensesRepository _repository;
private readonly IMapper _mapper;

public GetExpenseQueryHandler(IExpensesRepository repository)
public GetExpenseQueryHandler(IExpensesRepository repository, IMapper mapper)
{
_repository = repository;
_mapper = mapper;
}

public async Task<ExpenseDTO> Handle(
Expand All @@ -22,13 +24,7 @@ await _repository.GetBySpecAsync(
cancellationToken
) ?? throw new NotFoundException(request.Id);

return new ExpenseDTO(
expense.Id,
expense.Name,
expense.Description,
expense.Value,
expense.CategoryId
);
return _mapper.Map<ExpenseDTO>(expense);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/Application/Features/Shared/CategoryDTO.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
namespace Application.Features.Shared;

public record CategoryDTO(Guid Id, string Name, string Description, List<Expense> Expenses);
public record CategoryDTO(Guid Id, string Name, string Description, List<ExpenseDTO> Expenses);
3 changes: 2 additions & 1 deletion src/Application/GlobalUsings.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
global using Application.Abstractions;
global using Application.Contexts;
global using Application.Features.Commands;
global using Application.Features.DomainEvents;
global using Application.Features.Shared;
global using Application.Messages;
global using Application.Repositories;
global using Application.Requests;
global using Ardalis.Specification;
global using AutoMapper;
global using Domain.Cache;
global using Domain.Entities;
global using Domain.Exceptions;
Expand Down
13 changes: 13 additions & 0 deletions src/Application/Profiles/CategoriesProfile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace Application.Profiles;

public class CategoriesProfile : Profile
{
public CategoriesProfile()
{
CreateMap<Category, CategoryDTO>();
CreateMap<Category, PatchedCategoryEvent>();
CreateMap<Category, PostedCategoryEvent>();
CreateMap<PatchCategoryCommand, Category>();
CreateMap<PostCategoryCommand, Category>();
}
}
Loading

0 comments on commit 110c4c4

Please sign in to comment.