Skip to content

Commit

Permalink
Merge pull request #32 from AngeloDotNet/develop
Browse files Browse the repository at this point in the history
Sync Main from Develop
  • Loading branch information
AngeloDotNet authored Nov 17, 2024
2 parents 770528c + 86ca7ba commit 6dca614
Show file tree
Hide file tree
Showing 6 changed files with 268 additions and 2 deletions.
12 changes: 12 additions & 0 deletions src/GSWCloudApp.Common/Entities/BaseEntityConfiguration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace GSWCloudApp.Common.Entities;

public abstract class BaseEntityConfiguration<T> : IEntityTypeConfiguration<T> where T : BaseEntity<Guid>
{
public virtual void Configure(EntityTypeBuilder<T> builder)
{
builder.HasKey(x => x.Id);
}
}
44 changes: 44 additions & 0 deletions src/GSWCloudApp.Common/Extensions/ApplicationExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using GSWCloudApp.Common.Options;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.Extensions.Hosting;

namespace GSWCloudApp.Common.Extensions;

public static class ApplicationExtensions
{
public static void UseDevSwagger(this WebApplication app, ApplicationOptions options)
{
if (app.Environment.IsDevelopment() || options.SwaggerEnable)
{
app.UseSwagger();
app.UseSwaggerUI(options =>
{
var descriptions = app.DescribeApiVersions();
foreach (var description in descriptions)
{
var url = $"/swagger/{description.GroupName}/swagger.json";
options.SwaggerEndpoint(url, description.GroupName);
}
});
}
}

public static void UseForwardNetworking(this WebApplication app)
{
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});

// Non necessario se viene usato NGINX come proxy
// app.UseHttpsRedirection();
}

public static void UseAuthentication(this WebApplication app)
{
app.UseAuthentication();
app.UseAuthorization();
}
}
6 changes: 4 additions & 2 deletions src/GSWCloudApp.Common/GSWCloudApp.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Authors>Angelo Pirola</Authors>
<Product>Gestione sagre commonm library extension</Product>
<Product>Gestione sagre common library extension</Product>
<Description>Open source dotnet extension library for project gestione sagre web cloud app</Description>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/AngeloDotNet/GSWCloudApp/tree/main/GSWCloudApp.Common</PackageProjectUrl>
Expand All @@ -16,7 +16,9 @@

<ItemGroup>
<PackageReference Include="Asp.Versioning.Mvc.ApiExplorer" Version="8.1.0" />
<PackageReference Include="FluentValidation" Version="11.10.0" />
<PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="FluentValidation" Version="11.11.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.11" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.2" />
<PackageReference Include="Nerdbank.GitVersioning" Version="3.6.146">
<PrivateAssets>all</PrivateAssets>
Expand Down
2 changes: 2 additions & 0 deletions src/GSWCloudApp.Common/Options/ApplicationOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ public class ApplicationOptions
{
public string TabellaMigrazioni { get; set; } = null!;
public bool SwaggerEnable { get; set; }
public int MaxRetryCount { get; set; }
public int MaxRetryDelaySeconds { get; set; }
}
173 changes: 173 additions & 0 deletions src/GSWCloudApp.Common/Service/GenericService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
using AutoMapper;
using GSWCloudApp.Common.RedisCache;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace GSWCloudApp.Common.Service;

public class GenericService : IGenericService
{
public async Task<Results<Ok<List<TDto>>, NotFound>> GetAllAsync<TEntity, TDto>([FromQuery] bool cacheData, DbContext dbContext, ICacheService cacheService, IMapper mapper)
where TEntity : class
where TDto : class
{
var cacheKey = typeof(TEntity).Name;
var entity = new List<TEntity>();

if (!cacheData)
{
entity = await dbContext.Set<TEntity>().AsNoTracking().ToListAsync();

if (entity.Count == 0)
{
return TypedResults.NotFound();
}

return TypedResults.Ok(mapper.Map<List<TDto>>(entity));
}

entity = await cacheService.GetCacheAsync<List<TEntity>>(cacheKey);

if (entity != null)
{
return TypedResults.Ok(mapper.Map<List<TDto>>(entity));
}

entity = await dbContext.Set<TEntity>()
.AsNoTracking()
.ToListAsync();

if (entity.Count == 0)
{
return TypedResults.NotFound();
}

await cacheService.SetCacheAsync(cacheKey, entity);

var result = mapper.Map<List<TDto>>(entity);

return TypedResults.Ok(result);
}

public async Task<Results<Ok<TDto>, NotFound>> GetByIdAsync<TEntity, TDto>(Guid id, DbContext dbContext, ICacheService cacheService, IMapper mapper)
where TEntity : class
where TDto : class
{
var cacheKey = $"{typeof(TEntity).Name}-{id}";
var entity = await cacheService.GetCacheAsync<TEntity>(cacheKey);

if (entity != null)
{
return TypedResults.Ok(mapper.Map<TDto>(entity));
}

entity = await dbContext.Set<TEntity>()
.AsNoTracking()
.FirstOrDefaultAsync(e => EF.Property<Guid>(e, "Id") == id);

if (entity is null)
{
return TypedResults.NotFound();
}

await cacheService.SetCacheAsync(cacheKey, entity);

var result = mapper.Map<TDto>(entity);

return TypedResults.Ok(result);
}

public async Task<Results<Ok<TDto>, BadRequest<string>>> PostAsync<TEntity, TDto, TCreateDto>(TCreateDto createDto, DbContext dbContext, IMapper mapper)
where TEntity : class
where TDto : class
{
var entity = mapper.Map<TEntity>(createDto);

dbContext.Set<TEntity>().Add(entity);

try
{
await dbContext.SaveChangesAsync();

return TypedResults.Ok(mapper.Map<TDto>(entity));
}
catch (Exception ex)
{
return TypedResults.BadRequest(ex.Message);
}
}

public async Task<Results<Ok<TDto>, NotFound, BadRequest<string>>> UpdateAsync<TEntity, TDto, TEditDto>(Guid id, TEditDto editDto, DbContext dbContext, IMapper mapper)
where TEntity : class
where TDto : class
{
var entity = await dbContext.Set<TEntity>().FindAsync(id);

if (entity is null)
{
return TypedResults.NotFound();
}

mapper.Map(editDto, entity);

dbContext.Set<TEntity>().Update(entity);

try
{
await dbContext.SaveChangesAsync();

return TypedResults.Ok(mapper.Map<TDto>(entity));
}
catch (Exception ex)
{
return TypedResults.BadRequest(ex.Message);
}
}

public async Task<Results<NoContent, NotFound>> DeleteAsync<TEntity>(Guid id, DbContext dbContext)
where TEntity : class
{
var entity = await dbContext.Set<TEntity>()
.AsNoTracking()
.FirstOrDefaultAsync(e => EF.Property<Guid>(e, "Id") == id);

if (entity is null)
{
return TypedResults.NotFound();
}

dbContext.Set<TEntity>().Remove(entity);
await dbContext.SaveChangesAsync();

return TypedResults.NoContent();
}

public async Task<Results<Ok<List<TDto>>, NotFound>> FilterAsync<TEntity, TDto>(Guid festaId, DbContext dbContext, ICacheService cacheService, IMapper mapper)
where TEntity : class
where TDto : class
{
var cacheKey = $"{typeof(TEntity).Name}-{festaId}";
var entity = await cacheService.GetCacheAsync<List<TEntity>>(cacheKey);

if (entity != null)
{
return TypedResults.Ok(mapper.Map<List<TDto>>(entity));
}

entity = await dbContext.Set<TEntity>()
.AsNoTracking()
.Where(e => EF.Property<Guid>(e, "FestaId") == festaId)
.ToListAsync();

if (entity.Count == 0)
{
return TypedResults.NotFound();
}

await cacheService.SetCacheAsync(cacheKey, entity);

return TypedResults.Ok(mapper.Map<List<TDto>>(entity));
}
}
33 changes: 33 additions & 0 deletions src/GSWCloudApp.Common/Service/IGenericService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using AutoMapper;
using GSWCloudApp.Common.RedisCache;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace GSWCloudApp.Common.Service;

public interface IGenericService
{
Task<Results<Ok<List<TDto>>, NotFound>> GetAllAsync<TEntity, TDto>([FromQuery] bool cacheData, DbContext dbContext, ICacheService cacheService, IMapper mapper)
where TEntity : class
where TDto : class;

Task<Results<Ok<TDto>, NotFound>> GetByIdAsync<TEntity, TDto>(Guid id, DbContext dbContext, ICacheService cacheService, IMapper mapper)
where TEntity : class
where TDto : class;

Task<Results<Ok<TDto>, BadRequest<string>>> PostAsync<TEntity, TDto, TCreateDto>(TCreateDto createDto, DbContext dbContext, IMapper mapper)
where TEntity : class
where TDto : class;

Task<Results<Ok<TDto>, NotFound, BadRequest<string>>> UpdateAsync<TEntity, TDto, TEditDto>(Guid id, TEditDto editDto, DbContext dbContext, IMapper mapper)
where TEntity : class
where TDto : class;

Task<Results<NoContent, NotFound>> DeleteAsync<TEntity>(Guid id, DbContext dbContext)
where TEntity : class;

Task<Results<Ok<List<TDto>>, NotFound>> FilterAsync<TEntity, TDto>(Guid festaId, DbContext dbContext, ICacheService cacheService, IMapper mapper)
where TEntity : class
where TDto : class;
}

0 comments on commit 6dca614

Please sign in to comment.