GQL dynamic query :)

This commit is contained in:
David Lebee
2021-02-04 13:51:31 -05:00
parent ffcfc60df1
commit edf9258a85
22 changed files with 643 additions and 18 deletions
@@ -0,0 +1,84 @@
using HotChocolate.Types;
using PoweredSoft.CQRS.Abstractions;
using PoweredSoft.CQRS.Abstractions.Discovery;
using PoweredSoft.CQRS.DynamicQuery.Discover;
using System;
namespace PoweredSoft.CQRS.GraphQL.HotChocolate.DynamicQuery
{
internal class DynamicQueryObjectType : ObjectTypeExtension
{
private readonly IQueryDiscovery queryDiscovery;
public DynamicQueryObjectType(IQueryDiscovery queryDiscovery) : base()
{
this.queryDiscovery = queryDiscovery;
}
protected override void Configure(IObjectTypeDescriptor descriptor)
{
base.Configure(descriptor);
descriptor.Name("Query");
foreach(var q in queryDiscovery.GetQueries())
{
if (q.Category == "DynamicQuery" && q is DynamicQueryMeta dq)
{
var f = descriptor.Field(q.LowerCamelCaseName);
// service to execute with.
var queryHandlerServiceType = typeof(IQueryHandler<,>).MakeGenericType(dq.QueryType, dq.QueryResultType);
// destermine argument type.
Type argumentType;
Type runnerType;
if (dq.ParamsType != null)
{
argumentType = typeof(GraphQL.DynamicQuery.GraphQLDynamicQuery<,,>).MakeGenericType(
dq.SourceType, dq.DestinationType, dq.ParamsType);
runnerType = typeof(DynamicQueryRunnerWithParams<,,>)
.MakeGenericType(dq.SourceType, dq.DestinationType, dq.ParamsType);
}
else
{
argumentType = typeof(GraphQL.DynamicQuery.GraphQLDynamicQuery<,>).MakeGenericType(
dq.SourceType, dq.DestinationType);
runnerType = typeof(DynamicQueryRunner<,>)
.MakeGenericType(dq.SourceType, dq.DestinationType);
}
f.Argument("params", a => a
.Type(argumentType)
.DefaultValue(Activator.CreateInstance(argumentType))
);
// make generic type of outgoing type.
var resultType = typeof(GraphQL.DynamicQuery.GraphQLDynamicQueryExecutionResult<>)
.MakeGenericType(dq.DestinationType);
f.Type(resultType);
// resolver
f.Resolve(async r =>
{
dynamic argument = r.ArgumentValue<object>("params");
// handler service.
var service = r.Service(queryHandlerServiceType);
// runner.
dynamic runner = Activator.CreateInstance(runnerType, new object[] { service });
// get outcome.
object outcome = await runner.RunAsync(argument, r.RequestAborted);
return outcome;
});
}
}
}
}
}
@@ -0,0 +1,28 @@
using PoweredSoft.CQRS.DynamicQuery;
using PoweredSoft.CQRS.DynamicQuery.Abstractions;
using PoweredSoft.CQRS.GraphQL.DynamicQuery;
using System.Threading;
using System.Threading.Tasks;
namespace PoweredSoft.CQRS.GraphQL.HotChocolate.DynamicQuery
{
public class DynamicQueryRunner<TSource, TDestination>
where TSource : class
where TDestination : class
{
private readonly DynamicQueryHandler<TSource, TDestination> handler;
public DynamicQueryRunner(DynamicQueryHandler<TSource, TDestination> handler)
{
this.handler = handler;
}
public async Task<GraphQLDynamicQueryExecutionResult<TDestination>> RunAsync(IDynamicQuery<TSource, TDestination> query, CancellationToken cancellationToken = default)
{
var result = await handler.HandleAsync(query);
var outcome = new GraphQLDynamicQueryExecutionResult<TDestination>();
outcome.FromResult(result);
return outcome;
}
}
}
@@ -0,0 +1,29 @@
using PoweredSoft.CQRS.DynamicQuery;
using PoweredSoft.CQRS.DynamicQuery.Abstractions;
using PoweredSoft.CQRS.GraphQL.DynamicQuery;
using System.Threading;
using System.Threading.Tasks;
namespace PoweredSoft.CQRS.GraphQL.HotChocolate.DynamicQuery
{
public class DynamicQueryRunnerWithParams<TSource, TDestination, TParams>
where TSource : class
where TDestination : class
where TParams : class
{
private readonly DynamicQueryHandler<TSource, TDestination, TParams> handler;
public DynamicQueryRunnerWithParams(DynamicQueryHandler<TSource, TDestination, TParams> handler)
{
this.handler = handler;
}
public async Task<GraphQLDynamicQueryExecutionResult<TDestination>> RunAsync(IDynamicQuery<TSource, TDestination, TParams> query, CancellationToken cancellationToken = default)
{
var result = await handler.HandleAsync(query);
var outcome = new GraphQLDynamicQueryExecutionResult<TDestination>();
outcome.FromResult(result);
return outcome;
}
}
}
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="HotChocolate" Version="11.0.9" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PoweredSoft.CQRS.Abstractions\PoweredSoft.CQRS.Abstractions.csproj" />
<ProjectReference Include="..\PoweredSoft.CQRS.GraphQL.DynamicQuery\PoweredSoft.CQRS.GraphQL.DynamicQuery.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,15 @@
using HotChocolate.Execution.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
namespace PoweredSoft.CQRS.GraphQL.HotChocolate.DynamicQuery
{
public static class RequestExecutorBuilderExtensions
{
public static IRequestExecutorBuilder AddPoweredSoftDynamicQueries(this IRequestExecutorBuilder builder)
{
builder.AddTypeExtension<DynamicQueryObjectType>();
return builder;
}
}
}