cat on a spaceship

This commit is contained in:
2025-11-01 22:38:46 -04:00
parent 747fa227a1
commit f6dccf46d7
89 changed files with 2663 additions and 581 deletions
@@ -0,0 +1,61 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Svrnty.CQRS.Abstractions;
using Svrnty.CQRS.AspNetCore.Abstractions.Attributes;
using Svrnty.CQRS.DynamicQuery.Abstractions;
using PoweredSoft.DynamicQuery.Core;
namespace Svrnty.CQRS.DynamicQuery.AspNetCore.Mvc;
[ApiController, Route("api/query/[controller]")]
public class DynamicQueryController<TUnderlyingQuery, TSource, TDestination> : Controller
where TSource : class
where TDestination : class
{
[HttpPost, QueryControllerAuthorization]
public async Task<IQueryExecutionResult<TDestination>> HandleAsync(
[FromBody] DynamicQuery<TSource, TDestination> query,
[FromServices]IQueryHandler<IDynamicQuery<TSource, TDestination>, IQueryExecutionResult<TDestination>> queryHandler
)
{
var result = await queryHandler.HandleAsync(query, HttpContext.RequestAborted);
return result;
}
[HttpGet, QueryControllerAuthorization]
public async Task<IQueryExecutionResult<TDestination>> HandleGetAsync(
[FromQuery] DynamicQuery<TSource, TDestination> query,
[FromServices] IQueryHandler<IDynamicQuery<TSource, TDestination>, IQueryExecutionResult<TDestination>> queryHandler
)
{
var result = await queryHandler.HandleAsync(query, HttpContext.RequestAborted);
return result;
}
}
[ApiController, Route("api/query/[controller]")]
public class DynamicQueryController<TUnderlyingQuery, TSource, TDestination, TParams> : Controller
where TSource : class
where TDestination : class
where TParams : class
{
[HttpPost, QueryControllerAuthorization]
public async Task<IQueryExecutionResult<TDestination>> HandleAsync(
[FromBody] DynamicQuery<TSource, TDestination, TParams> query,
[FromServices] IQueryHandler<IDynamicQuery<TSource, TDestination, TParams>, IQueryExecutionResult<TDestination>> queryHandler
)
{
var result = await queryHandler.HandleAsync(query, HttpContext.RequestAborted);
return result;
}
[HttpGet, QueryControllerAuthorization]
public async Task<IQueryExecutionResult<TDestination>> HandleGetAsync(
[FromQuery] DynamicQuery<TSource, TDestination, TParams> query,
[FromServices] IQueryHandler<IDynamicQuery<TSource, TDestination, TParams>, IQueryExecutionResult<TDestination>> queryHandler
)
{
var result = await queryHandler.HandleAsync(query, HttpContext.RequestAborted);
return result;
}
}
@@ -0,0 +1,27 @@
using System;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.Extensions.DependencyInjection;
using Svrnty.CQRS.Abstractions.Discovery;
namespace Svrnty.CQRS.DynamicQuery.AspNetCore.Mvc;
public class DynamicQueryControllerConvention : IControllerModelConvention
{
private readonly IServiceProvider _serviceProvider;
public DynamicQueryControllerConvention(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public void Apply(ControllerModel controller)
{
if (controller.ControllerType.IsGenericType && controller.ControllerType.Name.Contains("DynamicQueryController") && controller.ControllerType.Assembly == typeof(DynamicQueryControllerConvention).Assembly)
{
var genericType = controller.ControllerType.GenericTypeArguments[0];
var queryDiscovery = _serviceProvider.GetRequiredService<IQueryDiscovery>();
var query = queryDiscovery.FindQuery(genericType);
controller.ControllerName = query.LowerCamelCaseName;
}
}
}
@@ -0,0 +1,80 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.DependencyInjection;
using Svrnty.CQRS.Abstractions.Discovery;
using Svrnty.CQRS.AspNetCore.Abstractions.Attributes;
using Svrnty.CQRS.DynamicQuery.Discover;
namespace Svrnty.CQRS.DynamicQuery.AspNetCore.Mvc;
public class DynamicQueryControllerFeatureProvider(ServiceProvider serviceProvider)
: IApplicationFeatureProvider<ControllerFeature>
{
/**
* public void PopulateFeature(IEnumerable<ApplicationPart> parts, ControllerFeature feature)
{
var queryDiscovery = this.serviceProvider.GetRequiredService<IQueryDiscovery>();
foreach (var f in queryDiscovery.GetQueries())
{
var ignoreAttribute = f.QueryType.GetCustomAttribute<QueryControllerIgnoreAttribute>();
if (ignoreAttribute != null)
continue;
if (f.Category != "DynamicQuery")
continue;
if (f is DynamicQueryMeta dynamicQueryMeta)
{
if (dynamicQueryMeta.ParamsType == null)
{
var controllerType = typeof(DynamicQueryController<,,>).MakeGenericType(f.QueryType, dynamicQueryMeta.SourceType, dynamicQueryMeta.DestinationType);
var controllerTypeInfo = controllerType.GetTypeInfo();
feature.Controllers.Add(controllerTypeInfo);
}
else
{
var controllerType = typeof(DynamicQueryController<,,,>).MakeGenericType(f.QueryType, dynamicQueryMeta.SourceType, dynamicQueryMeta.DestinationType, dynamicQueryMeta.ParamsType);
var controllerTypeInfo = controllerType.GetTypeInfo();
feature.Controllers.Add(controllerTypeInfo);
}
}
}
*/
public void PopulateFeature(IEnumerable<ApplicationPart> parts, ControllerFeature feature)
{
var queryDiscovery = serviceProvider.GetRequiredService<IQueryDiscovery>();
foreach (var queryMeta in queryDiscovery.GetQueries())
{
var ignoreAttribute = queryMeta.QueryType.GetCustomAttribute<QueryControllerIgnoreAttribute>();
if (ignoreAttribute != null)
continue;
if (queryMeta.Category != "DynamicQuery")
continue;
if (queryMeta is DynamicQueryMeta dynamicQueryMeta)
{
// todo: add better error output for the user
if (dynamicQueryMeta.ParamsType == null)
{
// todo: not aot friendly
var controllerType = typeof(DynamicQueryController<,,>).MakeGenericType(queryMeta.QueryType, dynamicQueryMeta.SourceType, dynamicQueryMeta.DestinationType);
var controllerTypeInfo = controllerType.GetTypeInfo();
feature.Controllers.Add(controllerTypeInfo);
}
else
{
// todo: not aot friendly
var controllerType = typeof(DynamicQueryController<,,,>).MakeGenericType(queryMeta.QueryType, dynamicQueryMeta.SourceType, dynamicQueryMeta.DestinationType, dynamicQueryMeta.ParamsType);
var controllerTypeInfo = controllerType.GetTypeInfo();
feature.Controllers.Add(controllerTypeInfo);
}
}
}
}
}
@@ -0,0 +1,5 @@
namespace Svrnty.CQRS.DynamicQuery.AspNetCore.Mvc;
public class DynamicQueryControllerOptions
{
}