Skip to content

Commit

Permalink
Fixed resolver compiler did not use the GraphQL argument name for fie…
Browse files Browse the repository at this point in the history
…ld args. (#5736)
  • Loading branch information
michaelstaib committed Jan 31, 2023
1 parent a6519a1 commit aebd140
Show file tree
Hide file tree
Showing 55 changed files with 535 additions and 267 deletions.
Expand Up @@ -38,14 +38,15 @@ internal sealed class ReferenceResolverArgumentExpressionBuilder

protected override string GetKey(ParameterInfo parameter) => DataField;

public override Expression Build(ParameterInfo parameter, Expression context)
public override Expression Build(ParameterExpressionBuilderContext context)
{
var path = Expression.Constant(GetPath(parameter), typeof(string[]));
var param = context.Parameter;
var path = Expression.Constant(GetPath(param), typeof(string[]));
var dataKey = Expression.Constant(DataField, typeof(string));
var typeKey = Expression.Constant(TypeField, typeof(string));
var value = BuildGetter(parameter, dataKey, context, typeof(IValueNode));
var objectType = BuildGetter(parameter, typeKey, context, typeof(ObjectType));
var getValueMethod = _getValue.MakeGenericMethod(parameter.ParameterType);
var value = BuildGetter(param, dataKey, context.ResolverContext, typeof(IValueNode));
var objectType = BuildGetter(param, typeKey, context.ResolverContext, typeof(ObjectType));
var getValueMethod = _getValue.MakeGenericMethod(param.ParameterType);
Expression getValue = Expression.Call(getValueMethod, value, objectType, path);
return getValue;
}
Expand All @@ -58,12 +59,11 @@ private string[] GetPath(ParameterInfo parameter)

if (Required.Count == 0)
{
Required = new string[][] { path };
Required = new[] { path };
}
else if (Required.Count == 1)
{
var required = new List<string[]>(Required);
required.Add(path);
var required = new List<string[]>(Required) { path };
Required = required;
}
else if (Required is List<string[]> list)
Expand Down
@@ -1,6 +1,7 @@
using HotChocolate.AspNetCore;
using Microsoft.Extensions.DependencyInjection.Extensions;
using HotChocolate.AspNetCore.Instrumentation;
using HotChocolate.AspNetCore.ParameterExpressionBuilders;
using HotChocolate.AspNetCore.Serialization;
using HotChocolate.Execution.Configuration;
using HotChocolate.Internal;
Expand Down Expand Up @@ -67,6 +68,20 @@ public static partial class HotChocolateAspNetCoreServiceCollectionExtensions
HttpContextParameterExpressionBuilder>();
}

if (services.All(t => t.ImplementationType !=
typeof(HttpRequestParameterExpressionBuilder)))
{
services.AddSingleton<IParameterExpressionBuilder,
HttpRequestParameterExpressionBuilder>();
}

if (services.All(t => t.ImplementationType !=
typeof(HttpResponseParameterExpressionBuilder)))
{
services.AddSingleton<IParameterExpressionBuilder,
HttpResponseParameterExpressionBuilder>();
}

return services;
}

Expand Down
24 changes: 24 additions & 0 deletions src/HotChocolate/AspNetCore/src/AspNetCore/GlobalStateHelpers.cs
@@ -0,0 +1,24 @@
using HotChocolate.Resolvers;
using Microsoft.AspNetCore.Http;

namespace HotChocolate.AspNetCore;

internal static class GlobalStateHelpers
{
public static HttpContext GetHttpContext(IPureResolverContext context)
{
if (context.ContextData.TryGetValue(nameof(HttpContext), out var value) &&
value is HttpContext httpContext)
{
return httpContext;
}

throw new MissingStateException("Resolver", nameof(HttpContext), StateKind.Global);
}

public static HttpRequest GetHttpRequest(IPureResolverContext context)
=> GetHttpContext(context).Request;

public static HttpResponse GetHttpResponse(IPureResolverContext context)
=> GetHttpContext(context).Response;
}

This file was deleted.

@@ -0,0 +1,22 @@
using System.Linq.Expressions;
using System.Reflection;
using HotChocolate.Internal;
using HotChocolate.Resolvers;
using HotChocolate.Resolvers.Expressions;
using HotChocolate.Resolvers.Expressions.Parameters;
using HotChocolate.Utilities;
using Microsoft.AspNetCore.Http;

namespace HotChocolate.AspNetCore.ParameterExpressionBuilders;

internal sealed class HttpContextParameterExpressionBuilder
: LambdaParameterExpressionBuilder<IPureResolverContext, HttpContext>
{
public HttpContextParameterExpressionBuilder()
: base(ctx => GlobalStateHelpers.GetHttpContext(ctx)) { }

public override ArgumentKind Kind => ArgumentKind.GlobalState;

public override bool CanHandle(ParameterInfo parameter)
=> parameter.ParameterType == typeof(HttpContext);
}
@@ -0,0 +1,20 @@
using System.Reflection;
using HotChocolate.Internal;
using HotChocolate.Resolvers;
using HotChocolate.Resolvers.Expressions.Parameters;
using Microsoft.AspNetCore.Http;

namespace HotChocolate.AspNetCore.ParameterExpressionBuilders;

internal sealed class HttpRequestParameterExpressionBuilder
: LambdaParameterExpressionBuilder<IPureResolverContext, HttpRequest>
{
public HttpRequestParameterExpressionBuilder()
: base(ctx => GlobalStateHelpers.GetHttpRequest(ctx)) { }

public override ArgumentKind Kind => ArgumentKind.GlobalState;

public override bool CanHandle(ParameterInfo parameter)
=> parameter.ParameterType == typeof(HttpRequest);
}

@@ -0,0 +1,20 @@
using System.Reflection;
using HotChocolate.Internal;
using HotChocolate.Resolvers;
using HotChocolate.Resolvers.Expressions.Parameters;
using Microsoft.AspNetCore.Http;

namespace HotChocolate.AspNetCore.ParameterExpressionBuilders;

internal sealed class HttpResponseParameterExpressionBuilder
: LambdaParameterExpressionBuilder<IPureResolverContext, HttpResponse>
{
public HttpResponseParameterExpressionBuilder()
: base(ctx => GlobalStateHelpers.GetHttpResponse(ctx)) { }

public override ArgumentKind Kind => ArgumentKind.GlobalState;

public override bool CanHandle(ParameterInfo parameter)
=> parameter.ParameterType == typeof(HttpResponse);
}

Expand Up @@ -78,7 +78,9 @@ public override Stream Body

public override string? ContentType
{
#pragma warning disable CS8764
get => Headers[HeaderNames.ContentType];
#pragma warning restore CS8764
set => Headers[HeaderNames.ContentType] = value;
}

Expand Down
Expand Up @@ -123,6 +123,9 @@ await ExecuteOperationAsync(context, batchDispatcher, context.Operation)
// if an operation is canceled we will abandon the the rented operation context
// to ensure that that abandoned tasks to not leak execution into new operations.
operationContextOwner = null;

// we rethrow so that another middleware can deal with the cancellation.
throw;
}
finally
{
Expand Down
Expand Up @@ -22,6 +22,8 @@ static DataLoaderParameterExpressionBuilder()
public override bool CanHandle(ParameterInfo parameter)
=> typeof(IDataLoader).IsAssignableFrom(parameter.ParameterType);

public override Expression Build(ParameterInfo parameter, Expression context)
=> Expression.Call(_dataLoader.MakeGenericMethod(parameter.ParameterType), context);
public override Expression Build(ParameterExpressionBuilderContext context)
=> Expression.Call(
_dataLoader.MakeGenericMethod(context.Parameter.ParameterType),
context.ResolverContext);
}
Expand Up @@ -34,16 +34,14 @@ public abstract class CustomParameterExpressionBuilder : IParameterExpressionBui
/// <summary>
/// Builds an expression that resolves a resolver parameter.
/// </summary>
/// <param name="parameter">
/// The parameter that needs to be resolved.
/// </param>
/// <param name="context">
/// An expression that represents the resolver context.
/// The parameter expression builder context.
/// </param>
/// <returns>
/// Returns an expression that resolves the value for this <paramref name="parameter"/>.
/// Returns an expression the handles the value injection into the parameter specified by
/// <see cref="ParameterExpressionBuilderContext.Parameter"/>.
/// </returns>
public abstract Expression Build(ParameterInfo parameter, Expression context);
public abstract Expression Build(ParameterExpressionBuilderContext context);
}

/// <summary>
Expand Down Expand Up @@ -86,9 +84,29 @@ public sealed class CustomParameterExpressionBuilder<TArg> : CustomParameterExpr

}

/// <summary>
/// Checks if this expression builder can handle the following parameter.
/// </summary>
/// <param name="parameter">
/// The parameter that needs to be resolved.
/// </param>
/// <returns>
/// <c>true</c> if the parameter can be handled by this expression builder;
/// otherwise <c>false</c>.
/// </returns>
public override bool CanHandle(ParameterInfo parameter)
=> _canHandle(parameter);

public override Expression Build(ParameterInfo parameter, Expression context)
=> Expression.Invoke(_expression, context);
/// <summary>
/// Builds an expression that resolves a resolver parameter.
/// </summary>
/// <param name="context">
/// The parameter expression builder context.
/// </param>
/// <returns>
/// Returns an expression the handles the value injection into the parameter specified by
/// <see cref="ParameterExpressionBuilderContext.Parameter"/>.
/// </returns>
public override Expression Build(ParameterExpressionBuilderContext context)
=> Expression.Invoke(_expression, context.ResolverContext);
}
Expand Up @@ -37,6 +37,6 @@ public bool CanHandle(ParameterInfo parameter)
public void ApplyConfiguration(ParameterInfo parameter, ObjectFieldDescriptor descriptor)
=> ServiceExpressionHelper.ApplyConfiguration(parameter, descriptor, _kind);

public Expression Build(ParameterInfo parameter, Expression context)
=> ServiceExpressionHelper.Build(parameter, context, _kind);
public Expression Build(ParameterExpressionBuilderContext context)
=> ServiceExpressionHelper.Build(context.Parameter, context.ResolverContext, _kind);
}
@@ -1,5 +1,4 @@
using System.Linq.Expressions;
using System.Reflection;

#nullable enable

Expand Down Expand Up @@ -29,14 +28,12 @@ public interface IParameterExpressionBuilder : IParameterHandler
/// <summary>
/// Builds an expression that resolves a resolver parameter.
/// </summary>
/// <param name="parameter">
/// The parameter that needs to be resolved.
/// </param>
/// <param name="context">
/// An expression that represents the resolver context.
/// The parameter expression builder context.
/// </param>
/// <returns>
/// Returns an expression that resolves the value for this <paramref name="parameter"/>.
/// Returns an expression the handles the value injection into the parameter specified by
/// <see cref="ParameterExpressionBuilderContext.Parameter"/>.
/// </returns>
Expression Build(ParameterInfo parameter, Expression context);
Expression Build(ParameterExpressionBuilderContext context);
}

0 comments on commit aebd140

Please sign in to comment.