Skip to content

Commit

Permalink
implementing all crud options
Browse files Browse the repository at this point in the history
  • Loading branch information
Edgar Mesquita authored and Edgar Mesquita committed Aug 3, 2023
1 parent 9829689 commit 808b987
Show file tree
Hide file tree
Showing 18 changed files with 390 additions and 251 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ public class OrderMapper : IMapper<OrderData, Order>, IMapper<OrderRequest, Orde
```
### The services
```csharp
public interface IOrderService : ICrudServiceBase<Order, OrderRequest>
public interface IOrderService : ICrudService<Order, OrderRequest>
{

}
Expand Down Expand Up @@ -182,6 +182,6 @@ or

```csharp
...
app.MapAllCrud(assembly);
app.MapAllCrud(opt => opt.FromAssembly(assembly));
app.Run();
```
4 changes: 2 additions & 2 deletions src/eQuantic.Core.Api.Crud/Controllers/CrudControllerBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ namespace eQuantic.Core.Api.Crud.Controllers;
/// <typeparam name="TRequest"></typeparam>
public abstract class CrudControllerBase<TEntity, TRequest> : ControllerBase, ICrudController<TEntity, TRequest> where TEntity : class, new()
{
private readonly ICrudServiceBase<TEntity, TRequest> _service;
private readonly ICrudService<TEntity, TRequest> _service;

/// <summary>
/// Initializes a new instance of the <see cref="CrudControllerBase{TEntity, TRequest}"/> class
/// </summary>
/// <param name="service"></param>
protected CrudControllerBase(ICrudServiceBase<TEntity, TRequest> service)
protected CrudControllerBase(ICrudService<TEntity, TRequest> service)
{
_service = service;
}
Expand Down
71 changes: 50 additions & 21 deletions src/eQuantic.Core.Api.Crud/Extensions/WepApplicationExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,20 @@ public static class WepApplicationExtensions
/// Map all CRUD endpoints
/// </summary>
/// <param name="app"></param>
/// <param name="assembly"></param>
/// <param name="options">Map all CRUD options</param>
/// <returns></returns>
public static WebApplication MapAllCrud(this WebApplication app, Assembly assembly)
public static WebApplication MapAllCrud(this WebApplication app, Action<AllCrudOptions>? options = null)
{
var allCrudOptions = new AllCrudOptions();
options?.Invoke(allCrudOptions);

var extensionType = typeof(WepApplicationExtensions);

var assembly = allCrudOptions.GetAssembly() ?? Assembly.GetExecutingAssembly();
var types = assembly.GetTypes()
.Where(o =>
o is { IsAbstract: false, IsInterface: false } &&
o.GetInterfaces().Any(i => i == typeof(ICrudServiceBase)) &&
o.GetInterfaces().Any(i => i == typeof(ICrudService)) &&
o.GetCustomAttribute<MapCrudEndpointsAttribute>() != null);

foreach (var type in types)
Expand All @@ -45,7 +49,7 @@ public static WebApplication MapAllCrud(this WebApplication app, Assembly assemb

var crudInterface = interfaces
.FirstOrDefault(o =>
o.GenericTypeArguments.Length > 0 && o.GetGenericTypeDefinition() == typeof(ICrudServiceBase<,>));
o.GenericTypeArguments.Length > 0 && o.GetGenericTypeDefinition() == typeof(ICrudService<,>));

if (crudInterface == null)
{
Expand All @@ -54,7 +58,9 @@ public static WebApplication MapAllCrud(this WebApplication app, Assembly assemb

var entityType = crudInterface.GenericTypeArguments[0];
var requestType = crudInterface.GenericTypeArguments[1];

var crudOptions = allCrudOptions.GetOptions().ContainsKey(entityType)
? allCrudOptions.GetOptions()[entityType]
: null;
var method = extensionType.GetMethod(nameof(MapCrud))
?.MakeGenericMethod(entityType, requestType, serviceType);
method?.Invoke(null, new object?[]
Expand All @@ -65,39 +71,62 @@ public static WebApplication MapAllCrud(this WebApplication app, Assembly assemb
if (crudEndpoints.ReferenceType != null)
opt.WithReference(crudEndpoints.ReferenceType);
crudOptions?.Invoke(opt);
})
});
}

return app;
}

/// <summary>
/// Map CRUD endpoints
/// Map Readers endpoints
/// </summary>
/// <param name="app">The web application</param>
/// <param name="options">The options</param>
/// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TRequest"></typeparam>
/// <typeparam name="TService"></typeparam>
/// <returns></returns>
public static WebApplication MapCrud<TEntity, TRequest, TService>(this WebApplication app,
public static WebApplication MapReaders<TEntity, TService>(this WebApplication app,
Action<CrudOptions<TEntity>>? options = null)
where TEntity : class, new()
where TService : ICrudServiceBase<TEntity, TRequest>
where TService : IReaderService<TEntity>
{
var crudOptions = new CrudOptions<TEntity>();
options?.Invoke(crudOptions);

if ((crudOptions.Verbs & CrudEndpointVerbs.OnlyGetById) == CrudEndpointVerbs.OnlyGetById)
{
app.MapGetById<TEntity, TRequest, TService>(crudOptions);
app.MapGetById<TEntity, TService>(crudOptions);
}

if ((crudOptions.Verbs & CrudEndpointVerbs.OnlyGetPaged) == CrudEndpointVerbs.OnlyGetPaged)
{
app.MapGetPagedList<TEntity, TRequest, TService>(crudOptions);
app.MapGetPagedList<TEntity, TService>(crudOptions);
}

return app;
}

/// <summary>
/// Map CRUD endpoints
/// </summary>
/// <param name="app">The web application</param>
/// <param name="options">The options</param>
/// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TRequest"></typeparam>
/// <typeparam name="TService"></typeparam>
/// <returns></returns>
public static WebApplication MapCrud<TEntity, TRequest, TService>(this WebApplication app,
Action<CrudOptions<TEntity>>? options = null)
where TEntity : class, new()
where TService : ICrudService<TEntity, TRequest>
{
var crudOptions = new CrudOptions<TEntity>();
options?.Invoke(crudOptions);

app.MapReaders<TEntity, TService>(options);

if ((crudOptions.Verbs & CrudEndpointVerbs.OnlyCreate) == CrudEndpointVerbs.OnlyCreate)
{
Expand Down Expand Up @@ -132,13 +161,13 @@ private static string GetPattern<TEntity>(bool withId = false, Type? referenceTy
return pattern;
}

private static WebApplication MapGetById<TEntity, TRequest, TService>(this WebApplication app,
private static WebApplication MapGetById<TEntity, TService>(this WebApplication app,
CrudOptions<TEntity> options)
where TEntity : class, new()
where TService : ICrudServiceBase<TEntity, TRequest>
where TService : IReaderService<TEntity>
{
var pattern = GetPattern<TEntity>(true, options.Get.ReferenceType);
var handlers = new CrudEndpointHandlers<TEntity, TRequest, TService>(options);
var handlers = new ReaderEndpointHandlers<TEntity, TService>(options);
Delegate handler = options.Get.ReferenceType != null
? handlers.GetReferencedById
: handlers.GetById;
Expand All @@ -151,13 +180,13 @@ private static WebApplication MapGetById<TEntity, TRequest, TService>(this WebAp
return app;
}

private static WebApplication MapGetPagedList<TEntity, TRequest, TService>(this WebApplication app,
private static WebApplication MapGetPagedList<TEntity, TService>(this WebApplication app,
CrudOptions<TEntity> options)
where TEntity : class, new()
where TService : ICrudServiceBase<TEntity, TRequest>
where TService : IReaderService<TEntity>
{
var pattern = GetPattern<TEntity>(false, options.List.ReferenceType);
var handlers = new CrudEndpointHandlers<TEntity, TRequest, TService>(options);
var handlers = new ReaderEndpointHandlers<TEntity, TService>(options);
Delegate handler = options.List.ReferenceType != null
? handlers.GetReferencedPagedList
: handlers.GetPagedList;
Expand All @@ -172,7 +201,7 @@ private static WebApplication MapGetPagedList<TEntity, TRequest, TService>(this
private static WebApplication MapCreate<TEntity, TRequest, TService>(this WebApplication app,
CrudOptions<TEntity> options)
where TEntity : class, new()
where TService : ICrudServiceBase<TEntity, TRequest>
where TService : ICrudService<TEntity, TRequest>
{
var pattern = GetPattern<TEntity>(false, options.Create.ReferenceType);
var handlers = new CrudEndpointHandlers<TEntity, TRequest, TService>(options);
Expand All @@ -189,7 +218,7 @@ private static WebApplication MapCreate<TEntity, TRequest, TService>(this WebApp
private static WebApplication MapUpdate<TEntity, TRequest, TService>(this WebApplication app,
CrudOptions<TEntity> options)
where TEntity : class, new()
where TService : ICrudServiceBase<TEntity, TRequest>
where TService : ICrudService<TEntity, TRequest>
{
var pattern = GetPattern<TEntity>(true, options.Update.ReferenceType);
var handlers = new CrudEndpointHandlers<TEntity, TRequest, TService>(options);
Expand All @@ -207,7 +236,7 @@ private static WebApplication MapUpdate<TEntity, TRequest, TService>(this WebApp
private static WebApplication MapDelete<TEntity, TRequest, TService>(this WebApplication app,
CrudOptions<TEntity> options)
where TEntity : class, new()
where TService : ICrudServiceBase<TEntity, TRequest>
where TService : ICrudService<TEntity, TRequest>
{
var pattern = GetPattern<TEntity>(true, options.Delete.ReferenceType);
var handlers = new CrudEndpointHandlers<TEntity, TRequest, TService>(options);
Expand Down
91 changes: 1 addition & 90 deletions src/eQuantic.Core.Api.Crud/Handlers/CrudEndpointHandlers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace eQuantic.Core.Api.Crud.Handlers;
/// <typeparam name="TService"></typeparam>
public sealed class CrudEndpointHandlers<TEntity, TRequest, TService>
where TEntity : class, new()
where TService : ICrudServiceBase<TEntity, TRequest>
where TService : ICrudService<TEntity, TRequest>
{
private readonly CrudOptions<TEntity> _options;

Expand All @@ -30,78 +30,6 @@ public CrudEndpointHandlers(CrudOptions<TEntity> options)
{
_options = options;
}

/// <summary>
/// Get referenced entity by identifier
/// </summary>
/// <param name="referenceId"></param>
/// <param name="id"></param>
/// <param name="service"></param>
/// <returns></returns>
public async Task<Results<Ok<TEntity>, NotFound>> GetReferencedById(
[FromRoute] int referenceId,
[FromRoute] int id,
[FromServices]TService service)
{
var request = new ItemRequest<int>(referenceId, id);
return await GetById(request, service);
}

/// <summary>
/// Get entity by identifier
/// </summary>
/// <param name="id"></param>
/// <param name="service"></param>
/// <returns></returns>
public async Task<Results<Ok<TEntity>, NotFound>> GetById(
[FromRoute] int id,
[FromServices]TService service)
{
var request = new ItemRequest(id);
return await GetById(request, service);
}

/// <summary>
/// Get paged list of referenced entity by criteria
/// </summary>
/// <param name="referenceId"></param>
/// <param name="pageIndex"></param>
/// <param name="pageSize"></param>
/// <param name="filterBy"></param>
/// <param name="orderBy"></param>
/// <param name="service"></param>
/// <returns></returns>
public async Task<Ok<PagedListResult<TEntity>>> GetReferencedPagedList(
[FromRoute] int referenceId,
[FromQuery] int? pageIndex,
[FromQuery] int? pageSize,
[FromQuery] IFiltering[]? filterBy,
[FromQuery] ISorting[]? orderBy,
[FromServices]TService service)
{
var request = new PagedListRequest<TEntity,int>(referenceId, pageIndex, pageSize, filterBy, orderBy);
return await GetPagedList(request, service);
}

/// <summary>
/// Get paged list of entity by criteria
/// </summary>
/// <param name="pageIndex"></param>
/// <param name="pageSize"></param>
/// <param name="filterBy"></param>
/// <param name="orderBy"></param>
/// <param name="service"></param>
/// <returns></returns>
public async Task<Ok<PagedListResult<TEntity>>> GetPagedList(
[FromQuery] int? pageIndex,
[FromQuery] int? pageSize,
[FromQuery] IFiltering[]? filterBy,
[FromQuery] ISorting[]? orderBy,
[FromServices]TService service)
{
var request = new PagedListRequest<TEntity>(pageIndex, pageSize, filterBy, orderBy);
return await GetPagedList(request, service);
}

/// <summary>
/// Create an entity
Expand Down Expand Up @@ -197,23 +125,6 @@ public async Task<Results<Ok, BadRequest>> ReferencedDelete(
return await Delete(request, service);
}

private static async Task<Results<Ok<TEntity>, NotFound>> GetById(ItemRequest request, TService service)
{
var result = await service.GetByIdAsync(request);
if (result != null)
return TypedResults.Ok(result);

return TypedResults.NotFound();
}

private static async Task<Ok<PagedListResult<TEntity>>> GetPagedList(
PagedListRequest<TEntity> request,
TService service)
{
var result = await service.GetPagedListAsync(request);
return TypedResults.Ok(new PagedListResult<TEntity>(result));
}

private async Task<CreatedAtRoute<int>> Create(
CreateRequest<TRequest> request,
TService service)
Expand Down
Loading

0 comments on commit 808b987

Please sign in to comment.