Skip to content

Commit 72f4a82

Browse files
committed
More work
1 parent 36c86e9 commit 72f4a82

7 files changed

Lines changed: 143 additions & 79 deletions

File tree

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Text.Json.Serialization;
6+
using System.Text.Json;
7+
using System.Threading.Tasks;
8+
using System.Xml.Linq;
9+
10+
namespace Linq2GraphQL.Client.Common
11+
{
12+
public abstract class GraphQLTypeBase
13+
{
14+
15+
public T GetMethodValue<T>(string methodName, params object[] arguments)
16+
{
17+
var id = Utilities.GetArgumentsId(arguments);
18+
19+
__AdditionalProperties.TryGetValue(methodName + id, out var value);
20+
return value.Deserialize<T>();
21+
}
22+
23+
public T GetFirstMethodValue<T>(string methodName)
24+
{
25+
var keyValue = __AdditionalProperties.FirstOrDefault(e => e.Key.StartsWith(methodName));
26+
if (keyValue.Key == null)
27+
{
28+
return default;
29+
}
30+
31+
return keyValue.Value.Deserialize<T>();
32+
}
33+
34+
35+
36+
[JsonExtensionData]
37+
public Dictionary<string, JsonElement> __AdditionalProperties { get; set; } = new();
38+
}
39+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace Linq2GraphQL.Client.Common
8+
{
9+
public class LazyProperty<T>
10+
{
11+
bool _initialized = false;
12+
T _result;
13+
14+
public T Value(Func<T> fn)
15+
{
16+
if (!_initialized)
17+
{
18+
_result = fn();
19+
_initialized = true;
20+
}
21+
return _result;
22+
}
23+
}
24+
}

src/Linq2GraphQL.Client/GraphBase.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ public GraphBase(GraphClient client, string name, OperationType operationType, L
1111
{
1212
this.client = client;
1313
this.operationType = operationType;
14-
QueryNode = new QueryNode(typeof(T), name, arguments);
14+
QueryNode = new QueryNode(typeof(T), name, arguments, false, true);
15+
1516
}
1617

1718
public QueryNode QueryNode { get; }

src/Linq2GraphQL.Client/QueryNode.cs

Lines changed: 20 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10,43 +10,27 @@ public class QueryNode
1010
{
1111
private readonly bool mustHaveChildren;
1212
private readonly Type underlyingMemberType;
13+
private string argumentHashCodeId;
1314

14-
public QueryNode(MemberInfo member, string name = null, List<ArgumentValue> arguments = null, bool interfaceProperty = false)
15+
public QueryNode(MemberInfo member, string name = null, List<ArgumentValue> arguments = null, bool interfaceProperty = false, bool topLevel = false)
1516
{
16-
17-
//https://stackoverflow.com/questions/8094867/good-gethashcode-override-for-list-of-foo-objects-respecting-the-order
18-
var argValues = arguments?.Where(e => e.Value != null).Select(e => e.Value).ToList();
19-
if (argValues?.Any() == true)
20-
{
21-
var ll = "";
22-
foreach (var arg in argValues)
23-
{
24-
ll += arg.GetHashCode().ToString();
25-
}
26-
var hashCode = ll.GetHashCode();
27-
28-
if (hashCode< 0)
29-
{
30-
hashCode = hashCode * -1;
31-
}
32-
33-
ArgumentHashCode = hashCode;
34-
Alias = "Arg" + hashCode.ToString();
35-
}
36-
3717
Name = name ?? member.GetCustomAttribute<JsonPropertyNameAttribute>()?.Name ?? member.Name.ToCamelCase();
3818
Member = member;
3919
Arguments = arguments ?? new List<ArgumentValue>();
4020
underlyingMemberType = member.GetUnderlyingType();
4121
mustHaveChildren = MustHaveChildren(underlyingMemberType);
4222
InterfaceProperty = interfaceProperty;
4323

24+
if (!topLevel) {
25+
SetArgumentHashCodeId();
26+
}
27+
4428
}
4529

4630
public bool InterfaceProperty { get; internal set; }
4731
public string Name { get; internal set; }
4832
public string Alias { get; internal set; }
49-
public int ArgumentHashCode { get; internal set; }
33+
5034
public MemberInfo Member { get; internal set; }
5135
public List<QueryNode> ChildNodes { get; internal set; } = new();
5236
public List<ArgumentValue> Arguments { get; internal set; } = new();
@@ -63,6 +47,16 @@ internal void IncludePrimitiveIfNoChildPrimitive()
6347
}
6448
}
6549

50+
private void SetArgumentHashCodeId()
51+
{
52+
argumentHashCodeId = Utilities.GetArgumentsId(Arguments?.Select(e=> e.Value));
53+
if (argumentHashCodeId != null)
54+
{
55+
Alias = Name + argumentHashCodeId;
56+
}
57+
}
58+
59+
6660
private static bool MustHaveChildren(Type type)
6761
{
6862
return !type.IsValueTypeOrString() &&
@@ -91,14 +85,7 @@ public void AddChildNode(MemberInfo member, string name = null)
9185

9286
public void AddChildNode(QueryNode childNode)
9387
{
94-
95-
if (childNode.ArgumentHashCode != 0)
96-
{
97-
var tt = "ss";
98-
}
99-
100-
101-
var currentNode = ChildNodes.FirstOrDefault(e => e.Name == childNode.Name && e.ArgumentHashCode == childNode.ArgumentHashCode);
88+
var currentNode = ChildNodes.FirstOrDefault(e => e.Name == childNode.Name && e.argumentHashCodeId == childNode.argumentHashCodeId);
10289
if (currentNode == null)
10390
{
10491
childNode.Parent = this;
@@ -228,7 +215,7 @@ internal string GetQueryString(string indent = "")
228215
{
229216
string query;
230217
var memberType = Member.GetUnderlyingType();
231-
218+
232219
if (InterfaceProperty)
233220
{
234221
query = "... on " + Name + GetArgumentString() + Environment.NewLine;
@@ -237,11 +224,10 @@ internal string GetQueryString(string indent = "")
237224
else if (!string.IsNullOrWhiteSpace(Alias))
238225
{
239226
query = Alias + ":" + Name + GetArgumentString() + Environment.NewLine;
240-
}
227+
}
241228
else
242229
{
243230
query = Name + GetArgumentString() + Environment.NewLine;
244-
245231
}
246232

247233
if (memberType.IsListOfPrimitiveTypeOrString())

src/Linq2GraphQL.Client/Utilities.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,37 @@
11
using System.Linq.Expressions;
22
using System.Reflection;
3+
using System.Reflection.Metadata.Ecma335;
34

45
namespace Linq2GraphQL.Client;
56

67
public static class Utilities
78
{
9+
10+
public static string GetArgumentsId(IEnumerable<object> objects)
11+
{
12+
if (objects == null) return null;
13+
var objs = objects.Where(o => o != null);
14+
if (!objs.Any()) return null;
15+
16+
unchecked
17+
{
18+
int hash = 19;
19+
foreach (var obj in objs)
20+
{
21+
hash = hash * 31 + obj.GetHashCode();
22+
}
23+
var hashString = hash.ToString().Replace("-", "_");
24+
25+
return hashString;
26+
}
27+
}
28+
829
public static bool IsSelectOrSelectMany(this MethodCallExpression methodCallExpression)
930
{
1031
if (methodCallExpression.Arguments.Count != 2) { return false; };
1132
var methodName = methodCallExpression.Method.Name;
1233
return (methodName == "Select" || methodName == "SelectMany");
13-
34+
1435
}
1536

1637
public static void ParseExpression(Expression body, QueryNode parent)

test/Linq2GraphQL.TestClient/Generated/Types/Order.cs

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,67 +2,61 @@
22
using System.Collections.Generic;
33
using System.Text.Json;
44
using System.Text.Json.Serialization;
5+
using System.Xml.Linq;
56
using Linq2GraphQL.Client;
7+
using Linq2GraphQL.Client.Common;
68

79
namespace Linq2GraphQL.TestClient;
810

911
public static class OrderExtensions
1012
{
1113
[GraphMethod("orderHello")]
12-
public static string OrderHello(this Order order, [GraphArgument("String!")] string name, [GraphArgument("Int!")] int first)
14+
public static string OrderHello(this Order order, [GraphArgument("String!")] string name, [GraphArgument("Int!")] int first)
1315
{
14-
var ll = "";
15-
if (name != null) { ll += name.GetHashCode().ToString(); }
16-
if(first != null) { ll += first.GetHashCode().ToString(); }
17-
18-
var argHascode = ll.GetHashCode();
19-
if (argHascode < 0) { argHascode = argHascode * -1; }
20-
21-
var vall = order.__AdditionalProperties["Arg" + argHascode];
22-
return vall.Deserialize<string>();
23-
16+
return order.GetMethodValue<string>("orderHello", name, first);
2417
}
2518

2619
[GraphMethod("orderAddress")]
27-
public static Address OrderAddress(this Order order, [GraphArgument("AddressType!")] AddressType addressType)
20+
public static Address OrderAddress(this Order order, [GraphArgument("AddressType!")] AddressType addressType)
2821
{
29-
return order?.OrderAddress;
22+
return order.GetMethodValue<Address>("orderAddress", addressType);
3023
}
3124

3225
}
3326

34-
public partial class Order
27+
public partial class Order : GraphQLTypeBase
3528
{
29+
30+
private LazyProperty<string> _orderHello = new();
3631
/// <summary>
3732
/// Do not use in Query, only to retrive result
3833
/// </summary>
3934
[GraphShadowProperty]
40-
[JsonPropertyName("orderHello")]
41-
public string OrderHello { get; set; }
35+
public string OrderHello => _orderHello.Value(() => GetFirstMethodValue<string>("orderHello"));
4236

37+
38+
private LazyProperty<Address> _orderAddress = new();
4339
/// <summary>
4440
/// Do not use in Query, only to retrive result
4541
/// </summary>
4642
[GraphShadowProperty]
47-
[JsonPropertyName("orderAddress")]
48-
public Address OrderAddress { get; set; }
43+
public Address OrderAddress => _orderAddress.Value(() => GetFirstMethodValue<Address>("orderAddress"));
44+
45+
[JsonPropertyName("orderId")]
46+
public Guid OrderId { get; set; }
4947

50-
[JsonPropertyName("orderId")]
51-
public Guid OrderId { get; set; }
48+
[JsonPropertyName("customer")]
49+
public Customer Customer { get; set; }
5250

53-
[JsonPropertyName("customer")]
54-
public Customer Customer { get; set; }
51+
[JsonPropertyName("address")]
52+
public Address Address { get; set; }
5553

56-
[JsonPropertyName("address")]
57-
public Address Address { get; set; }
54+
[JsonPropertyName("orderDate")]
55+
public DateTimeOffset OrderDate { get; set; }
5856

59-
[JsonPropertyName("orderDate")]
60-
public DateTimeOffset OrderDate { get; set; }
57+
[JsonPropertyName("lines")]
58+
public List<OrderLine> Lines { get; set; }
6159

62-
[JsonPropertyName("lines")]
63-
public List<OrderLine> Lines { get; set; }
6460

65-
[JsonExtensionData]
66-
public Dictionary<string, JsonElement> __AdditionalProperties { get; set; }
6761

6862
}

test/Linq2GraphQL.Tests/QueryArgumentTests.cs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
1-
using GreenDonut;
2-
using Linq2GraphQL.TestClient;
3-
using System;
4-
using System.Collections.Generic;
5-
using System.Linq;
6-
using System.Text;
7-
using System.Threading.Tasks;
1+
using Linq2GraphQL.TestClient;
82

93
namespace Linq2GraphQL.Tests
104
{
@@ -29,7 +23,6 @@ public async Task TopAndInQueryArguments_SameName()
2923
.Select(e => e.Nodes);
3024

3125
var request = await query.GetRequestAsync();
32-
3326
var result = await query.ExecuteAsync();
3427

3528
Assert.Single(result);
@@ -46,6 +39,10 @@ public async Task TopLevelArguments()
4639
var request = await query.GetRequestAsync();
4740
var result = await query.ExecuteAsync();
4841

42+
var order = result.First();
43+
44+
var address = order.OrderAddress;
45+
4946
Assert.Single(result);
5047
}
5148

@@ -62,20 +59,22 @@ public async Task InQueryArguments()
6259

6360
var result = await query.ExecuteAsync();
6461

65-
Assert.NotNull(result.First().OrderAddress);
66-
Assert.Equal("Invoice", result.First().OrderAddress.Name);
62+
var order = result.First();
63+
64+
Assert.NotNull(order.OrderAddress);
65+
Assert.Equal("Invoice", result.First().OrderAddress?.Name);
6766
}
6867

6968
[Fact]
7069
public async Task InQueryAnonymousType()
7170
{
7271
var query = sampleClient
7372
.Query
74-
.Orders()
73+
.Orders(first: 2)
7574
.Include(e => e.Nodes)
76-
.Select(e => e.Nodes.Select(e => e.OrderHello("Jocke", 123)));
75+
.Select(e => e.Nodes.Select(e => e.OrderHello("Kalle", 123)));
7776

78-
var gQ = query.GetRequestAsync();
77+
var gQ = await query.GetRequestAsync();
7978

8079
var node = query.QueryNode;
8180
var result = await query.ExecuteAsync();

0 commit comments

Comments
 (0)