Skip to content

Commit

Permalink
improving crud options
Browse files Browse the repository at this point in the history
  • Loading branch information
Edgar Mesquita authored and Edgar Mesquita committed Aug 8, 2023
1 parent 808b987 commit 03f7dc4
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 48 deletions.
111 changes: 87 additions & 24 deletions src/eQuantic.Core.Api.Crud/Extensions/WepApplicationExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ public static WebApplication MapAllCrud(this WebApplication app, Action<AllCrudO
var types = assembly.GetTypes()
.Where(o =>
o is { IsAbstract: false, IsInterface: false } &&
o.GetInterfaces().Any(i => i == typeof(ICrudService)) &&
o.GetInterfaces()
.Any(i => i == typeof(IReaderService)) &&
o.GetCustomAttribute<MapCrudEndpointsAttribute>() != null);

foreach (var type in types)
Expand All @@ -47,39 +48,27 @@ public static WebApplication MapAllCrud(this WebApplication app, Action<AllCrudO
continue;
}

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

if (crudInterface == null)
{
continue;
}
var readerInterface = GetReaderServiceInterface(interfaces);

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?[]
{
app, (Action<ICrudOptions>?)(opt =>
if (readerInterface == null)
{
opt.WithVerbs(crudEndpoints.EndpointVerbs);
if (crudEndpoints.ReferenceType != null)
opt.WithReference(crudEndpoints.ReferenceType);
continue;
}

InvokeMapReaders(app, readerInterface, allCrudOptions, extensionType, serviceType, crudEndpoints);
continue;
}

crudOptions?.Invoke(opt);
})
});
InvokeMapCrud(app, crudInterface, allCrudOptions, extensionType, serviceType, crudEndpoints);
}

return app;
}

/// <summary>
/// Map Readers endpoints
/// </summary>
Expand Down Expand Up @@ -145,7 +134,76 @@ public static WebApplication MapCrud<TEntity, TRequest, TService>(this WebApplic

return app;
}

private static Type? GetCrudServiceInterface(IEnumerable<Type> interfaces)
{
return interfaces
.FirstOrDefault(o =>
o.GenericTypeArguments.Length > 0 && o.GetGenericTypeDefinition() == typeof(ICrudService<,>));
}

private static Type? GetReaderServiceInterface(IEnumerable<Type> interfaces)
{
return interfaces
.FirstOrDefault(o =>
o.GenericTypeArguments.Length > 0 && o.GetGenericTypeDefinition() == typeof(IReaderService<>));
}

private static Action<ICrudOptions>? GetCrudOptions(AllCrudOptions allCrudOptions, Type entityType)
{
return allCrudOptions.GetOptions().ContainsKey(entityType)
? allCrudOptions.GetOptions()[entityType]
: null;
}

private static void InvokeMapCrud(WebApplication app, Type crudInterface, AllCrudOptions allCrudOptions,
Type extensionType, Type serviceType, MapCrudEndpointsAttribute crudEndpoints)
{
var entityType = crudInterface.GenericTypeArguments[0];
var requestType = crudInterface.GenericTypeArguments[1];
var crudOptions = GetCrudOptions(allCrudOptions, entityType);
var method = extensionType.GetMethod(nameof(MapCrud))
?.MakeGenericMethod(entityType, requestType, serviceType);

InvokeMethod(app, crudEndpoints, method, allCrudOptions, crudOptions);
}

private static void InvokeMapReaders(WebApplication app, Type crudInterface, AllCrudOptions allCrudOptions,
Type extensionType, Type serviceType, MapCrudEndpointsAttribute crudEndpoints)
{
var entityType = crudInterface.GenericTypeArguments[0];
var crudOptions = GetCrudOptions(allCrudOptions, entityType);
var method = extensionType.GetMethod(nameof(MapReaders))
?.MakeGenericMethod(entityType, serviceType);

InvokeMethod(app, crudEndpoints, method, allCrudOptions, crudOptions);
}

private static void InvokeMethod(
WebApplication app,
MapCrudEndpointsAttribute crudEndpoints,
MethodBase? method,
AllCrudOptions allCrudOptions,
Action<ICrudOptions>? crudOptions)
{
method?.Invoke(null, new object?[]
{
app, (Action<ICrudOptions>?)(opt =>
{
opt.WithVerbs(crudEndpoints.EndpointVerbs);
if (crudEndpoints.ReferenceType != null)
opt.WithReference(crudEndpoints.ReferenceType);
if (allCrudOptions.GetRequireAuth() == true)
{
opt.RequireAuthorization();
}
crudOptions?.Invoke(opt);
})
});
}

private static string GetPattern<TEntity>(bool withId = false, Type? referenceType = null)
{
var entityType = typeof(TEntity);
Expand Down Expand Up @@ -253,6 +311,7 @@ private static WebApplication MapDelete<TEntity, TRequest, TService>(this WebApp
private static RouteHandlerBuilder SetOptions<TEntity>(this RouteHandlerBuilder endpoint, EndpointOptions options)
{
endpoint.WithName(options.Name);

if (!string.IsNullOrEmpty(options.Summary))
{
endpoint.WithSummary(options.Summary);
Expand All @@ -270,6 +329,10 @@ private static RouteHandlerBuilder SetOptions<TEntity>(this RouteHandlerBuilder

endpoint.WithOpenApi();

if (options.RequireAuth == true)
{
endpoint.RequireAuthorization();
}
return endpoint;
}
}
5 changes: 1 addition & 4 deletions src/eQuantic.Core.Api.Crud/Handlers/CrudEndpointHandlers.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
using eQuantic.Core.Api.Crud.Options;
using eQuantic.Core.Application.Crud.Entities.Requests;
using eQuantic.Core.Application.Crud.Services;
using eQuantic.Core.Application.Entities.Results;
using eQuantic.Linq.Filter;
using eQuantic.Linq.Sorter;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;
Expand All @@ -16,7 +13,7 @@ namespace eQuantic.Core.Api.Crud.Handlers;
/// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TRequest"></typeparam>
/// <typeparam name="TService"></typeparam>
public sealed class CrudEndpointHandlers<TEntity, TRequest, TService>
internal sealed class CrudEndpointHandlers<TEntity, TRequest, TService>
where TEntity : class, new()
where TService : ICrudService<TEntity, TRequest>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

namespace eQuantic.Core.Api.Crud.Handlers;

public class ReaderEndpointHandlers<TEntity, TService>
internal class ReaderEndpointHandlers<TEntity, TService>
where TEntity : class, new()
where TService : IReaderService<TEntity>
{
Expand Down
10 changes: 9 additions & 1 deletion src/eQuantic.Core.Api.Crud/Options/AllCrudOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,28 @@ public class AllCrudOptions
{
private Assembly? _assembly = null;
private readonly Dictionary<Type, Action<ICrudOptions>> _options = new();

private bool? _requireAuth = null;

public AllCrudOptions FromAssembly(Assembly assembly)
{
_assembly = assembly;
return this;
}

public AllCrudOptions AllRequireAuthorization()
{
_requireAuth = true;
return this;
}

public EntityCrudOptions<TEntity> For<TEntity>()
{
return new EntityCrudOptions<TEntity>(this);
}

internal Assembly? GetAssembly() => _assembly;
internal Dictionary<Type, Action<ICrudOptions>> GetOptions() => _options;
internal bool? GetRequireAuth() => _requireAuth;

public class EntityCrudOptions<TEntity>
{
Expand Down
34 changes: 28 additions & 6 deletions src/eQuantic.Core.Api.Crud/Options/CrudOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ public interface ICrudOptions
EndpointOptions Get { get; }
EndpointOptions List { get; }
EndpointOptions Delete { get; }


ICrudOptions RequireAuthorization();
ICrudOptions WithVerbs(CrudEndpointVerbs verbs);
ICrudOptions WithReference(Type referenceType);
ICrudOptions WithReference<TReferenceEntity>();
Expand All @@ -26,6 +27,16 @@ public ICrudOptions WithVerbs(CrudEndpointVerbs verbs)
Verbs = verbs;
return this;
}

public ICrudOptions RequireAuthorization()
{
Get.RequireAuthorization();
List.RequireAuthorization();
Create.RequireAuthorization();
Update.RequireAuthorization();
Delete.RequireAuthorization();
return this;
}

/// <summary>
/// Options with referenced entity
Expand Down Expand Up @@ -165,29 +176,40 @@ public EndpointOptions WithSummary(string summary)
Summary = summary;
return this;
}

public EndpointOptions RequireAuthorization()
{
RequireAuth = true;
return this;
}

/// <summary>
/// The reference entity type
/// </summary>
public Type? ReferenceType { get; private set; }
internal Type? ReferenceType { get; private set; }

/// <summary>
/// The endpoint name
/// </summary>
public string Name { get; private set; } = string.Empty;
internal string Name { get; private set; } = string.Empty;

/// <summary>
/// The endpoint description
/// </summary>
public string? Description { get; private set; }
internal string? Description { get; private set; }

/// <summary>
/// The endpoint summary
/// </summary>
public string? Summary { get; private set; }
internal string? Summary { get; private set; }

/// <summary>
/// The endpoint tags
/// </summary>
public string[] Tags { get; private set; } = Array.Empty<string>();
internal string[] Tags { get; private set; } = Array.Empty<string>();

/// <summary>
/// The endpoint authorization
/// </summary>
internal bool? RequireAuth { get; private set; }
}
6 changes: 3 additions & 3 deletions src/eQuantic.Core.Api.Crud/eQuantic.Core.Api.Crud.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
<Authors>eQuantic Systems</Authors>
<RootNamespace>eQuantic.Core.Api.Crud</RootNamespace>
<AssemblyTitle>eQuantic.Core.Api.Crud</AssemblyTitle>
<AssemblyVersion>1.0.9.0</AssemblyVersion>
<FileVersion>1.0.9.0</FileVersion>
<Version>1.0.9.0</Version>
<AssemblyVersion>1.0.10.0</AssemblyVersion>
<FileVersion>1.0.10.0</FileVersion>
<Version>1.0.10.0</Version>
<TargetFramework>net7.0</TargetFramework>

<PackageId>eQuantic.Core.Api.Crud</PackageId>
Expand Down
6 changes: 3 additions & 3 deletions src/eQuantic.Core.Api/eQuantic.Core.Api.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
<Authors>eQuantic Systems</Authors>
<RootNamespace>eQuantic.Core.Api</RootNamespace>
<AssemblyTitle>eQuantic.Core.Api</AssemblyTitle>
<AssemblyVersion>1.0.9.0</AssemblyVersion>
<FileVersion>1.0.9.0</FileVersion>
<Version>1.0.9.0</Version>
<AssemblyVersion>1.0.10.0</AssemblyVersion>
<FileVersion>1.0.10.0</FileVersion>
<Version>1.0.10.0</Version>
<TargetFramework>net7.0</TargetFramework>

<PackageId>eQuantic.Core.Api</PackageId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
<Authors>eQuantic Systems</Authors>
<RootNamespace>eQuantic.Core.Application.Crud</RootNamespace>
<AssemblyTitle>eQuantic.Core.Application.Crud</AssemblyTitle>
<AssemblyVersion>1.0.9.0</AssemblyVersion>
<FileVersion>1.0.9.0</FileVersion>
<Version>1.0.9.0</Version>
<AssemblyVersion>1.0.10.0</AssemblyVersion>
<FileVersion>1.0.10.0</FileVersion>
<Version>1.0.10.0</Version>
<TargetFrameworks>netstandard2.1;net7.0</TargetFrameworks>

<PackageId>eQuantic.Core.Application.Crud</PackageId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
<Authors>eQuantic Systems</Authors>
<RootNamespace>eQuantic.Core.Application</RootNamespace>
<AssemblyTitle>eQuantic.Core.Application</AssemblyTitle>
<AssemblyVersion>1.0.9.0</AssemblyVersion>
<FileVersion>1.0.9.0</FileVersion>
<Version>1.0.9.0</Version>
<AssemblyVersion>1.0.10.0</AssemblyVersion>
<FileVersion>1.0.10.0</FileVersion>
<Version>1.0.10.0</Version>
<TargetFrameworks>netstandard2.1;net7.0</TargetFrameworks>

<PackageId>eQuantic.Core.Application</PackageId>
Expand Down

0 comments on commit 03f7dc4

Please sign in to comment.