GQL dynamic query :)
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
@@ -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>
|
||||
+15
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user