Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -57,21 +57,15 @@ protected virtual void WriteResolverBindings(IOutputTypeInfo type)
return;
}

if (type.Resolvers.Any(t => t.Bindings.Length > 0))
if (type.Resolvers.SelectMany(t => t.Bindings).Any(b => b.Kind is MemberBindingKind.Property))
{
Writer.WriteLine();
Writer.WriteIndentedLine("var naming = descriptor.Extend().Context.Naming;");
Writer.WriteIndentedLine("var ignoredFields = new global::System.Collections.Generic.HashSet<string>();");

foreach (var binding in type.Resolvers.SelectMany(t => t.Bindings))
{
if (binding.Kind is MemberBindingKind.Field)
{
Writer.WriteIndentedLine(
"ignoredFields.Add(\"{0}\");",
binding.Name);
}
else if (binding.Kind is MemberBindingKind.Property)
if (binding.Kind is MemberBindingKind.Property)
{
Writer.WriteIndentedLine(
"ignoredFields.Add(naming.GetMemberName(\"{0}\", global::{1}.ObjectField));",
Expand All @@ -98,12 +92,23 @@ protected virtual void WriteResolverBindings(IOutputTypeInfo type)

using (Writer.IncreaseIndent())
{
Writer.WriteIndentedLine(
".Field(thisType.GetMember(\"{0}\", global::{1})[0])",
resolver.Member.Name,
resolver.IsStatic
? WellKnownTypes.StaticMemberFlags
: WellKnownTypes.InstanceMemberFlags);
// Check if this resolver has a field binding (BindField attribute)
var fieldBinding = resolver.Bindings.FirstOrDefault(b => b.Kind is MemberBindingKind.Field);
if (fieldBinding.Name is not null)
{
// For BindField, configure the bound field name instead of creating a new field from the method
Writer.WriteIndentedLine(".Field(\"{0}\")", fieldBinding.Name);
}
else
{
// For regular resolvers, create field from method name
Writer.WriteIndentedLine(
".Field(thisType.GetMember(\"{0}\", global::{1})[0])",
resolver.Member.Name,
resolver.IsStatic
? WellKnownTypes.StaticMemberFlags
: WellKnownTypes.InstanceMemberFlags);
}

if (resolver.Kind is ResolverKind.ConnectionResolver)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,80 @@ internal static partial class BookNode
}
""").MatchMarkdownAsync();
}

[Fact]
public async Task GenerateSource_BindField_MatchesSnapshot()
{
await TestHelper.GetGeneratedSourceSnapshot(
"""
using System;
using System.Threading;
using System.Threading.Tasks;
using HotChocolate;
using HotChocolate.Types;

namespace TestNamespace;

public sealed class LineItem
{
public int Id { get; set; }
public int ProductId { get; set; }
public int Quantity { get; set; }
}

public sealed class Product
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
}

[ObjectType<LineItem>]
public static partial class LineItemType
{
[BindField("product")]
public static Product GetProduct([Parent] LineItem lineItem)
=> new Product { Id = lineItem.ProductId, Name = "Test Product" };
}
""").MatchMarkdownAsync();
}

[Fact]
public async Task GenerateSource_BindField_And_BindMember_MatchesSnapshot()
{
await TestHelper.GetGeneratedSourceSnapshot(
"""
using System;
using System.Threading;
using System.Threading.Tasks;
using HotChocolate;
using HotChocolate.Types;

namespace TestNamespace;

public sealed class User
{
public int Id { get; set; }
public string Email { get; set; } = string.Empty;
public int ProfileId { get; set; }
}

public sealed class Profile
{
public int Id { get; set; }
public string DisplayName { get; set; } = string.Empty;
}

[ObjectType<User>]
public static partial class UserType
{
[BindField("profile")]
public static Profile GetProfile([Parent] User user)
=> new Profile { Id = user.ProfileId, DisplayName = "Profile" };

[BindMember(nameof(User.Email))]
public static string GetEmailFormatted([Parent] User user)
=> $"Email: {user.Email}";
}
""").MatchMarkdownAsync();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# GenerateSource_BindField_And_BindMember_MatchesSnapshot

## HotChocolateTypeModule.735550c.g.cs

```csharp
// <auto-generated/>

#nullable enable
#pragma warning disable

using System;
using System.Runtime.CompilerServices;
using HotChocolate;
using HotChocolate.Types;
using HotChocolate.Execution.Configuration;

namespace Microsoft.Extensions.DependencyInjection
{
public static partial class TestsTypesRequestExecutorBuilderExtensions
{
public static IRequestExecutorBuilder AddTestsTypes(this IRequestExecutorBuilder builder)
{
builder.ConfigureDescriptorContext(ctx => ctx.TypeConfiguration.TryAdd<global::TestNamespace.User>(
"Tests::TestNamespace.UserType",
() => global::TestNamespace.UserType.Initialize));
builder.AddType<ObjectType<global::TestNamespace.User>>();
return builder;
}
}
}

```

## UserType.WaAdMHmlGJHjtEI4nqY7WA.hc.g.cs

```csharp
// <auto-generated/>

#nullable enable
#pragma warning disable

using System;
using System.Runtime.CompilerServices;
using HotChocolate;
using HotChocolate.Types;
using HotChocolate.Execution.Configuration;
using Microsoft.Extensions.DependencyInjection;
using HotChocolate.Internal;

namespace TestNamespace
{
public static partial class UserType
{
internal static void Initialize(global::HotChocolate.Types.IObjectTypeDescriptor<global::TestNamespace.User> descriptor)
{
var thisType = typeof(global::TestNamespace.UserType);
var bindingResolver = descriptor.Extend().Context.ParameterBindingResolver;
var resolvers = new __Resolvers();

var naming = descriptor.Extend().Context.Naming;
var ignoredFields = new global::System.Collections.Generic.HashSet<string>();
ignoredFields.Add(naming.GetMemberName("Email", global::HotChocolate.Types.MemberKind.ObjectField));

foreach(string fieldName in ignoredFields)
{
descriptor.Field(fieldName).Ignore();
}

descriptor
.Field("profile")
.ExtendWith(static (c, r) =>
{
c.Configuration.SetSourceGeneratorFlags();
c.Configuration.Resolvers = r.GetProfile();
},
resolvers);

descriptor
.Field(thisType.GetMember("GetEmailFormatted", global::HotChocolate.Utilities.ReflectionUtils.StaticMemberFlags)[0])
.ExtendWith(static (c, r) =>
{
c.Configuration.SetSourceGeneratorFlags();
c.Configuration.Resolvers = r.GetEmailFormatted();
},
resolvers);

Configure(descriptor);
}

static partial void Configure(global::HotChocolate.Types.IObjectTypeDescriptor<global::TestNamespace.User> descriptor);

private sealed class __Resolvers
{
public HotChocolate.Resolvers.FieldResolverDelegates GetProfile()
{
return new global::HotChocolate.Resolvers.FieldResolverDelegates(pureResolver: GetProfile);
}

private global::System.Object? GetProfile(global::HotChocolate.Resolvers.IResolverContext context)
{
var args0 = context.Parent<global::TestNamespace.User>();
var result = global::TestNamespace.UserType.GetProfile(args0);
return result;
}

public HotChocolate.Resolvers.FieldResolverDelegates GetEmailFormatted()
{
return new global::HotChocolate.Resolvers.FieldResolverDelegates(pureResolver: GetEmailFormatted);
}

private global::System.Object? GetEmailFormatted(global::HotChocolate.Resolvers.IResolverContext context)
{
var args0 = context.Parent<global::TestNamespace.User>();
var result = global::TestNamespace.UserType.GetEmailFormatted(args0);
return result;
}
}
}
}


```

Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# GenerateSource_BindField_MatchesSnapshot

## HotChocolateTypeModule.735550c.g.cs

```csharp
// <auto-generated/>

#nullable enable
#pragma warning disable

using System;
using System.Runtime.CompilerServices;
using HotChocolate;
using HotChocolate.Types;
using HotChocolate.Execution.Configuration;

namespace Microsoft.Extensions.DependencyInjection
{
public static partial class TestsTypesRequestExecutorBuilderExtensions
{
public static IRequestExecutorBuilder AddTestsTypes(this IRequestExecutorBuilder builder)
{
builder.ConfigureDescriptorContext(ctx => ctx.TypeConfiguration.TryAdd<global::TestNamespace.LineItem>(
"Tests::TestNamespace.LineItemType",
() => global::TestNamespace.LineItemType.Initialize));
builder.AddType<ObjectType<global::TestNamespace.LineItem>>();
return builder;
}
}
}

```

## LineItemType.WaAdMHmlGJHjtEI4nqY7WA.hc.g.cs

```csharp
// <auto-generated/>

#nullable enable
#pragma warning disable

using System;
using System.Runtime.CompilerServices;
using HotChocolate;
using HotChocolate.Types;
using HotChocolate.Execution.Configuration;
using Microsoft.Extensions.DependencyInjection;
using HotChocolate.Internal;

namespace TestNamespace
{
public static partial class LineItemType
{
internal static void Initialize(global::HotChocolate.Types.IObjectTypeDescriptor<global::TestNamespace.LineItem> descriptor)
{
var thisType = typeof(global::TestNamespace.LineItemType);
var bindingResolver = descriptor.Extend().Context.ParameterBindingResolver;
var resolvers = new __Resolvers();

descriptor
.Field("product")
.ExtendWith(static (c, r) =>
{
c.Configuration.SetSourceGeneratorFlags();
c.Configuration.Resolvers = r.GetProduct();
},
resolvers);

Configure(descriptor);
}

static partial void Configure(global::HotChocolate.Types.IObjectTypeDescriptor<global::TestNamespace.LineItem> descriptor);

private sealed class __Resolvers
{
public HotChocolate.Resolvers.FieldResolverDelegates GetProduct()
{
return new global::HotChocolate.Resolvers.FieldResolverDelegates(pureResolver: GetProduct);
}

private global::System.Object? GetProduct(global::HotChocolate.Resolvers.IResolverContext context)
{
var args0 = context.Parent<global::TestNamespace.LineItem>();
var result = global::TestNamespace.LineItemType.GetProduct(args0);
return result;
}
}
}
}


```

Loading