From 423fd9f8d09dc7164679a40cacf6bd45327aa6a8 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 27 Jun 2026 12:36:27 +0200 Subject: [PATCH] fix(strawberryshake): dedupe duplicate fragment spreads in interface list Spreading the same named fragment two or more times in a single selection set caused the generated operation result type to list the fragment's generated interface more than once in its base-interface list, producing C# that fails to compile with CS0528 ('IUF' is already listed in interface list). Generation reported no error; only the downstream compile failed. Repros (valid GraphQL, fail to compile before this change): query Q { me { ...UF ...UF } } fragment UF on User { id name } query Q { node(id: "1") { ...NF ...NF } } fragment NF on Node { id } Root cause: FieldCollector.ResolveFragmentSpread adds one FragmentNode per spread, so duplicate spreads yield duplicate nodes. FragmentHelper.CreateImplements then iterates those nodes and adds the same cached interface OutputTypeModel once per spread. The existing IsImplementedBy dedup in CreateInterface only removes a model that is implemented by another model in the list, not a literal duplicate, so the duplicate base interface reached the generated C#. Fix: in CreateImplements, skip an interface model that is already present in the implements list. Models are cached one-per-name, so reference identity is sufficient. Output for single spreads, distinct fragments, same fragment at different levels, and union members is unchanged. Adds DuplicateFragmentSpreadGeneratorTests covering both repros plus four control cases; AssertResult Roslyn-compiles the output, so a CS0528 fails the test. --- .../Analyzers/FragmentHelper.cs | 12 +- .../DuplicateFragmentSpreadGeneratorTests.cs | 96 ++ ...e_Fragment_Spread_At_Different_Levels.snap | 905 ++++++++++++++++++ ...Fragment_Spread_Twice_On_Union_Member.snap | 841 ++++++++++++++++ ..._Same_Interface_Fragment_Spread_Twice.snap | 696 ++++++++++++++ ...hen_Same_Object_Fragment_Spread_Twice.snap | 726 ++++++++++++++ ...d_Compile_When_Single_Fragment_Spread.snap | 723 ++++++++++++++ ...e_When_Two_Different_Fragments_Spread.snap | 754 +++++++++++++++ 8 files changed, 4751 insertions(+), 2 deletions(-) create mode 100644 src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/DuplicateFragmentSpreadGeneratorTests.cs create mode 100644 src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/DuplicateFragmentSpreadGeneratorTests.Generate_Should_Compile_When_Same_Fragment_Spread_At_Different_Levels.snap create mode 100644 src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/DuplicateFragmentSpreadGeneratorTests.Generate_Should_Compile_When_Same_Fragment_Spread_Twice_On_Union_Member.snap create mode 100644 src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/DuplicateFragmentSpreadGeneratorTests.Generate_Should_Compile_When_Same_Interface_Fragment_Spread_Twice.snap create mode 100644 src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/DuplicateFragmentSpreadGeneratorTests.Generate_Should_Compile_When_Same_Object_Fragment_Spread_Twice.snap create mode 100644 src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/DuplicateFragmentSpreadGeneratorTests.Generate_Should_Compile_When_Single_Fragment_Spread.snap create mode 100644 src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/DuplicateFragmentSpreadGeneratorTests.Generate_Should_Compile_When_Two_Different_Fragments_Spread.snap diff --git a/src/StrawberryShake/CodeGeneration/src/CodeGeneration/Analyzers/FragmentHelper.cs b/src/StrawberryShake/CodeGeneration/src/CodeGeneration/Analyzers/FragmentHelper.cs index de8be54c391..62a778d43ac 100644 --- a/src/StrawberryShake/CodeGeneration/src/CodeGeneration/Analyzers/FragmentHelper.cs +++ b/src/StrawberryShake/CodeGeneration/src/CodeGeneration/Analyzers/FragmentHelper.cs @@ -455,8 +455,16 @@ private static IReadOnlyList CreateImplements( var fields = new HashSet(); levels.Push(fields); - implements.Add( - CreateInterface(context, child, selectionPath, levels, rootImplements)); + var @interface = + CreateInterface(context, child, selectionPath, levels, rootImplements); + + // the same named fragment can be spread more than once in a single selection + // set. Each spread resolves to the same cached interface model, so we must not + // list it twice or the generated type would declare a duplicate base interface. + if (!implements.Contains(@interface)) + { + implements.Add(@interface); + } // we add all the fields of this interface to the parent fields level so that we // do not create the interface field multiple time on the various levels. diff --git a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/DuplicateFragmentSpreadGeneratorTests.cs b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/DuplicateFragmentSpreadGeneratorTests.cs new file mode 100644 index 00000000000..14a7eda806c --- /dev/null +++ b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/DuplicateFragmentSpreadGeneratorTests.cs @@ -0,0 +1,96 @@ +using static StrawberryShake.CodeGeneration.CSharp.GeneratorTestHelper; + +namespace StrawberryShake.CodeGeneration.CSharp; + +public class DuplicateFragmentSpreadGeneratorTests +{ + private const string Schema = + "interface Node { id: ID! } " + + "type Query { me: User node(id: ID!): Node pet: Pet } " + + "type User implements Node { id: ID! name: String email: String bestFriend: User } " + + "union Pet = Dog | Cat " + + "type Dog { id: ID! name: String } " + + "type Cat { id: ID! name: String }"; + + private const string KeyExtension = "extend schema @key(fields: \"id\")"; + + [Fact] + public void Generate_Should_Compile_When_Same_Object_Fragment_Spread_Twice() + { + // arrange + // spreading the same fragment twice must not list its interface twice (CS0528). + + // act & assert + AssertResult( + "query Q { me { ...UF ...UF } } fragment UF on User { id name }", + Schema, + KeyExtension); + } + + [Fact] + public void Generate_Should_Compile_When_Same_Interface_Fragment_Spread_Twice() + { + // arrange + // duplicate spread on an interface-typed field must dedupe the base interface list. + + // act & assert + AssertResult( + "query Q { node(id: \"1\") { ...NF ...NF } } fragment NF on Node { id }", + Schema, + KeyExtension); + } + + [Fact] + public void Generate_Should_Compile_When_Single_Fragment_Spread() + { + // arrange + // control: a single spread already works and must keep working. + + // act & assert + AssertResult( + "query Q { me { ...UF } } fragment UF on User { id name }", + Schema, + KeyExtension); + } + + [Fact] + public void Generate_Should_Compile_When_Two_Different_Fragments_Spread() + { + // arrange + // control: two distinct fragments must both remain in the interface list. + + // act & assert + AssertResult( + "query Q { me { ...UF ...UG } } " + + "fragment UF on User { id name } " + + "fragment UG on User { email }", + Schema, + KeyExtension); + } + + [Fact] + public void Generate_Should_Compile_When_Same_Fragment_Spread_At_Different_Levels() + { + // arrange + // control: the same fragment at different selection levels must each be emitted. + + // act & assert + AssertResult( + "query Q { me { ...UF bestFriend { ...UF } } } fragment UF on User { id name }", + Schema, + KeyExtension); + } + + [Fact] + public void Generate_Should_Compile_When_Same_Fragment_Spread_Twice_On_Union_Member() + { + // arrange + // duplicate spread targeting a union member must also dedupe the base interface list. + + // act & assert + AssertResult( + "query Q { pet { ...DF ...DF } } fragment DF on Dog { name }", + Schema, + KeyExtension); + } +} diff --git a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/DuplicateFragmentSpreadGeneratorTests.Generate_Should_Compile_When_Same_Fragment_Spread_At_Different_Levels.snap b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/DuplicateFragmentSpreadGeneratorTests.Generate_Should_Compile_When_Same_Fragment_Spread_At_Different_Levels.snap new file mode 100644 index 00000000000..672d1c10d6b --- /dev/null +++ b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/DuplicateFragmentSpreadGeneratorTests.Generate_Should_Compile_When_Same_Fragment_Spread_At_Different_Levels.snap @@ -0,0 +1,905 @@ +// ReSharper disable ArrangeObjectCreationWhenTypeEvident +// ReSharper disable BuiltInTypeReferenceStyle +// ReSharper disable ConvertToAutoProperty +// ReSharper disable InconsistentNaming +// ReSharper disable PartialTypeWithSinglePart +// ReSharper disable PreferConcreteValueOverDefault +// ReSharper disable RedundantNameQualifier +// ReSharper disable SuggestVarOrType_SimpleTypes +// ReSharper disable UnusedMember.Global +// ReSharper disable UnusedMethodReturnValue.Local +// ReSharper disable UnusedType.Global +// ReSharper disable UnusedVariable + +// FooClient + +// +#nullable enable annotations +#nullable disable warnings + +namespace Foo.Bar +{ + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultTypeGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QResult : global::System.IEquatable, IQResult + { + public QResult(global::Foo.Bar.IQ_Me? me) + { + Me = me; + } + + public global::Foo.Bar.IQ_Me? Me { get; } + + public virtual global::System.Boolean Equals(QResult? other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (other.GetType() != GetType()) + { + return false; + } + + return (((Me is null && other.Me is null) || Me != null && Me.Equals(other.Me))); + } + + public override global::System.Boolean Equals(global::System.Object? obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != GetType()) + { + return false; + } + + return Equals((QResult)obj); + } + + public override global::System.Int32 GetHashCode() + { + unchecked + { + int hash = 5; + if (Me != null) + { + hash ^= 397 * Me.GetHashCode(); + } + + return hash; + } + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultTypeGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class Q_Me_User : global::System.IEquatable, IQ_Me_User + { + public Q_Me_User(global::System.String id, global::System.String? name, global::Foo.Bar.IQ_Me_BestFriend? bestFriend) + { + Id = id; + Name = name; + BestFriend = bestFriend; + } + + public global::System.String Id { get; } + public global::System.String? Name { get; } + public global::Foo.Bar.IQ_Me_BestFriend? BestFriend { get; } + + public virtual global::System.Boolean Equals(Q_Me_User? other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (other.GetType() != GetType()) + { + return false; + } + + return (Id.Equals(other.Id)) && ((Name is null && other.Name is null) || Name != null && Name.Equals(other.Name)) && ((BestFriend is null && other.BestFriend is null) || BestFriend != null && BestFriend.Equals(other.BestFriend)); + } + + public override global::System.Boolean Equals(global::System.Object? obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != GetType()) + { + return false; + } + + return Equals((Q_Me_User)obj); + } + + public override global::System.Int32 GetHashCode() + { + unchecked + { + int hash = 5; + hash ^= 397 * Id.GetHashCode(); + if (Name != null) + { + hash ^= 397 * Name.GetHashCode(); + } + + if (BestFriend != null) + { + hash ^= 397 * BestFriend.GetHashCode(); + } + + return hash; + } + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultTypeGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class Q_Me_BestFriend_User : global::System.IEquatable, IQ_Me_BestFriend_User + { + public Q_Me_BestFriend_User(global::System.String id, global::System.String? name) + { + Id = id; + Name = name; + } + + public global::System.String Id { get; } + public global::System.String? Name { get; } + + public virtual global::System.Boolean Equals(Q_Me_BestFriend_User? other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (other.GetType() != GetType()) + { + return false; + } + + return (Id.Equals(other.Id)) && ((Name is null && other.Name is null) || Name != null && Name.Equals(other.Name)); + } + + public override global::System.Boolean Equals(global::System.Object? obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != GetType()) + { + return false; + } + + return Equals((Q_Me_BestFriend_User)obj); + } + + public override global::System.Int32 GetHashCode() + { + unchecked + { + int hash = 5; + hash ^= 397 * Id.GetHashCode(); + if (Name != null) + { + hash ^= 397 * Name.GetHashCode(); + } + + return hash; + } + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IQResult + { + public global::Foo.Bar.IQ_Me? Me { get; } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IUF + { + public global::System.String Id { get; } + public global::System.String? Name { get; } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IQ_Me : IUF + { + public global::Foo.Bar.IQ_Me_BestFriend? BestFriend { get; } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IQ_Me_User : IQ_Me + { + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IQ_Me_BestFriend : IUF + { + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IQ_Me_BestFriend_User : IQ_Me_BestFriend + { + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.OperationDocumentGenerator + /// + /// Represents the operation service of the Q GraphQL operation + /// + /// query Q { + /// me { + /// __typename + /// ...UF + /// bestFriend { + /// __typename + /// ...UF + /// ... on User { + /// id + /// } + /// } + /// ... on User { + /// id + /// } + /// } + /// } + /// + /// fragment UF on User { + /// id + /// name + /// } + /// + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QQueryDocument : global::StrawberryShake.IDocument + { + private QQueryDocument() + { + } + + public static QQueryDocument Instance { get; } = new QQueryDocument(); + public global::StrawberryShake.OperationKind Kind => global::StrawberryShake.OperationKind.Query; + public global::System.ReadOnlySpan Body => "query Q { me { __typename ...UF bestFriend { __typename ...UF ... on User { id } } ... on User { id } } } fragment UF on User { id name }"u8; + public global::StrawberryShake.DocumentHash Hash { get; } = new global::StrawberryShake.DocumentHash("sha1Hash", "d74ee670ff3afc4f832cdee839cf6549a12e8248"); + + public override global::System.String ToString() + { +#if NETCOREAPP3_1_OR_GREATER + return global::System.Text.Encoding.UTF8.GetString(Body); +#else + return global::System.Text.Encoding.UTF8.GetString(Body.ToArray()); +#endif + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.OperationServiceGenerator + /// + /// Represents the operation service of the Q GraphQL operation + /// + /// query Q { + /// me { + /// __typename + /// ...UF + /// bestFriend { + /// __typename + /// ...UF + /// ... on User { + /// id + /// } + /// } + /// ... on User { + /// id + /// } + /// } + /// } + /// + /// fragment UF on User { + /// id + /// name + /// } + /// + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QQuery : global::Foo.Bar.IQQuery + { + private readonly global::StrawberryShake.IOperationExecutor _operationExecutor; + private readonly global::System.Collections.Immutable.ImmutableArray> _configure = global::System.Collections.Immutable.ImmutableArray>.Empty; + public QQuery(global::StrawberryShake.IOperationExecutor operationExecutor) + { + _operationExecutor = operationExecutor ?? throw new global::System.ArgumentNullException(nameof(operationExecutor)); + } + + private QQuery(global::StrawberryShake.IOperationExecutor operationExecutor, global::System.Collections.Immutable.ImmutableArray> configure) + { + _operationExecutor = operationExecutor; + _configure = configure; + } + + global::System.Type global::StrawberryShake.IOperationRequestFactory.ResultType => typeof(IQResult); + + public global::Foo.Bar.IQQuery With(global::System.Action configure) + { + return new global::Foo.Bar.QQuery(_operationExecutor, _configure.Add(configure)); + } + + public global::Foo.Bar.IQQuery WithRequestUri(global::System.Uri requestUri) + { + return With(r => r.ContextData["StrawberryShake.Transport.Http.HttpConnection.RequestUri"] = requestUri); + } + + public global::Foo.Bar.IQQuery WithHttpClient(global::System.Net.Http.HttpClient httpClient) + { + return With(r => r.ContextData["StrawberryShake.Transport.Http.HttpConnection.HttpClient"] = httpClient); + } + + public async global::System.Threading.Tasks.Task> ExecuteAsync(global::System.Threading.CancellationToken cancellationToken = default) + { + var request = CreateRequest(); + foreach (var configure in _configure) + { + configure(request); + } + + return await _operationExecutor.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + } + + public global::System.IObservable> Watch(global::StrawberryShake.ExecutionStrategy? strategy = null) + { + var request = CreateRequest(); + return _operationExecutor.Watch(request, strategy); + } + + private global::StrawberryShake.OperationRequest CreateRequest() + { + return CreateRequest(null); + } + + private global::StrawberryShake.OperationRequest CreateRequest(global::System.Collections.Generic.IReadOnlyDictionary? variables) + { + return new global::StrawberryShake.OperationRequest(id: QQueryDocument.Instance.Hash.Value, name: "Q", document: QQueryDocument.Instance, strategy: global::StrawberryShake.RequestStrategy.Default); + } + + global::StrawberryShake.OperationRequest global::StrawberryShake.IOperationRequestFactory.Create(global::System.Collections.Generic.IReadOnlyDictionary? variables) + { + return CreateRequest(); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.OperationServiceInterfaceGenerator + /// + /// Represents the operation service of the Q GraphQL operation + /// + /// query Q { + /// me { + /// __typename + /// ...UF + /// bestFriend { + /// __typename + /// ...UF + /// ... on User { + /// id + /// } + /// } + /// ... on User { + /// id + /// } + /// } + /// } + /// + /// fragment UF on User { + /// id + /// name + /// } + /// + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IQQuery : global::StrawberryShake.IOperationRequestFactory + { + global::Foo.Bar.IQQuery With(global::System.Action configure); + global::Foo.Bar.IQQuery WithRequestUri(global::System.Uri requestUri); + global::Foo.Bar.IQQuery WithHttpClient(global::System.Net.Http.HttpClient httpClient); + global::System.Threading.Tasks.Task> ExecuteAsync(global::System.Threading.CancellationToken cancellationToken = default); + global::System.IObservable> Watch(global::StrawberryShake.ExecutionStrategy? strategy = null); + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ClientGenerator + /// + /// Represents the FooClient GraphQL client + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class FooClient : global::Foo.Bar.IFooClient + { + private readonly global::Foo.Bar.IQQuery _q; + public FooClient(global::Foo.Bar.IQQuery q) + { + _q = q ?? throw new global::System.ArgumentNullException(nameof(q)); + } + + public static global::System.String ClientName => "FooClient"; + public global::Foo.Bar.IQQuery Q => _q; + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ClientInterfaceGenerator + /// + /// Represents the FooClient GraphQL client + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IFooClient + { + global::Foo.Bar.IQQuery Q { get; } + } +} + +namespace Foo.Bar.State +{ + // StrawberryShake.CodeGeneration.CSharp.Generators.EntityTypeGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "0.0.0.0")] + public partial class UserEntity + { + public UserEntity(global::System.String id = default !, global::System.String? name = default !, global::StrawberryShake.EntityId? bestFriend = default !) + { + Id = id; + Name = name; + BestFriend = bestFriend; + } + + public global::System.String Id { get; } + public global::System.String? Name { get; } + public global::StrawberryShake.EntityId? BestFriend { get; } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultDataFactoryGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QResultFactory : global::StrawberryShake.IOperationResultDataFactory + { + private readonly global::StrawberryShake.IEntityStore _entityStore; + private readonly global::StrawberryShake.IEntityMapper _q_Me_UserFromUserEntityMapper; + public QResultFactory(global::StrawberryShake.IEntityStore entityStore, global::StrawberryShake.IEntityMapper q_Me_UserFromUserEntityMapper) + { + _entityStore = entityStore ?? throw new global::System.ArgumentNullException(nameof(entityStore)); + _q_Me_UserFromUserEntityMapper = q_Me_UserFromUserEntityMapper ?? throw new global::System.ArgumentNullException(nameof(q_Me_UserFromUserEntityMapper)); + } + + global::System.Type global::StrawberryShake.IOperationResultDataFactory.ResultType => typeof(global::Foo.Bar.IQResult); + + public QResult Create(global::StrawberryShake.IOperationResultDataInfo dataInfo, global::StrawberryShake.IEntityStoreSnapshot? snapshot = null) + { + if (snapshot is null) + { + snapshot = _entityStore.CurrentSnapshot; + } + + if (dataInfo is QResultInfo info) + { + return new QResult(MapIQ_Me(info.Me, snapshot)); + } + + throw new global::System.ArgumentException("QResultInfo expected."); + } + + private global::Foo.Bar.IQ_Me? MapIQ_Me(global::StrawberryShake.EntityId? entityId, global::StrawberryShake.IEntityStoreSnapshot snapshot) + { + if (entityId is null) + { + return null; + } + + if (entityId.Value.Name.Equals("User", global::System.StringComparison.Ordinal)) + { + return _q_Me_UserFromUserEntityMapper.Map(snapshot.GetEntity(entityId.Value) ?? throw new global::StrawberryShake.GraphQLClientException()); + } + + throw new global::System.NotSupportedException(); + } + + global::System.Object global::StrawberryShake.IOperationResultDataFactory.Create(global::StrawberryShake.IOperationResultDataInfo dataInfo, global::StrawberryShake.IEntityStoreSnapshot? snapshot) + { + return Create(dataInfo, snapshot); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInfoGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QResultInfo : global::StrawberryShake.IOperationResultDataInfo + { + private readonly global::System.Collections.Generic.IReadOnlyCollection _entityIds; + private readonly global::System.UInt64 _version; + public QResultInfo(global::StrawberryShake.EntityId? me, global::System.Collections.Generic.IReadOnlyCollection entityIds, global::System.UInt64 version) + { + Me = me; + _entityIds = entityIds ?? throw new global::System.ArgumentNullException(nameof(entityIds)); + _version = version; + } + + public global::StrawberryShake.EntityId? Me { get; } + public global::System.Collections.Generic.IReadOnlyCollection EntityIds => _entityIds; + public global::System.UInt64 Version => _version; + + public global::StrawberryShake.IOperationResultDataInfo WithVersion(global::System.UInt64 version) + { + return new QResultInfo(Me, _entityIds, version); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.JsonResultBuilderGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QBuilder : global::StrawberryShake.OperationResultBuilder + { + private readonly global::StrawberryShake.IEntityStore _entityStore; + private readonly global::StrawberryShake.IEntityIdSerializer _idSerializer; + private readonly global::StrawberryShake.Serialization.ILeafValueParser _iDParser; + private readonly global::StrawberryShake.Serialization.ILeafValueParser _stringParser; + public QBuilder(global::StrawberryShake.IEntityStore entityStore, global::StrawberryShake.IEntityIdSerializer idSerializer, global::StrawberryShake.IOperationResultDataFactory resultDataFactory, global::StrawberryShake.Serialization.ISerializerResolver serializerResolver) + { + _entityStore = entityStore ?? throw new global::System.ArgumentNullException(nameof(entityStore)); + _idSerializer = idSerializer ?? throw new global::System.ArgumentNullException(nameof(idSerializer)); + ResultDataFactory = resultDataFactory ?? throw new global::System.ArgumentNullException(nameof(resultDataFactory)); + _iDParser = serializerResolver.GetLeafValueParser("ID") ?? throw new global::System.ArgumentException("No serializer for type `ID` found."); + _stringParser = serializerResolver.GetLeafValueParser("String") ?? throw new global::System.ArgumentException("No serializer for type `String` found."); + } + + protected override global::StrawberryShake.IOperationResultDataFactory ResultDataFactory { get; } + + protected override global::StrawberryShake.IOperationResultDataInfo BuildData(global::System.Text.Json.JsonElement obj) + { + var entityIds = new global::System.Collections.Generic.HashSet(); + global::StrawberryShake.IEntityStoreSnapshot snapshot = default !; + global::StrawberryShake.EntityId? meId = default !; + _entityStore.Update(session => + { + meId = Update_IQ_MeEntity(session, global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "me"), entityIds); + snapshot = session.CurrentSnapshot; + }); + return new QResultInfo(meId, entityIds, snapshot.Version); + } + + private global::StrawberryShake.EntityId? Update_IQ_MeEntity(global::StrawberryShake.IEntityStoreUpdateSession session, global::System.Text.Json.JsonElement? obj, global::System.Collections.Generic.ISet entityIds) + { + if (!obj.HasValue) + { + return null; + } + + if (obj.Value.ValueKind == global::System.Text.Json.JsonValueKind.Null) + { + return null; + } + + global::StrawberryShake.EntityId entityId = _idSerializer.Parse(obj.Value); + entityIds.Add(entityId); + if (entityId.Name.Equals("User", global::System.StringComparison.Ordinal)) + { + if (session.CurrentSnapshot.TryGetEntity(entityId, out global::Foo.Bar.State.UserEntity? entity)) + { + session.SetEntity(entityId, new global::Foo.Bar.State.UserEntity(Deserialize_NonNullableString(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "id")), Deserialize_String(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "name")), Update_IQ_Me_BestFriendEntity(session, global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "bestFriend"), entityIds))); + } + else + { + session.SetEntity(entityId, new global::Foo.Bar.State.UserEntity(Deserialize_NonNullableString(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "id")), Deserialize_String(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "name")), Update_IQ_Me_BestFriendEntity(session, global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "bestFriend"), entityIds))); + } + + return entityId; + } + + throw new global::System.NotSupportedException(); + } + + private global::System.String Deserialize_NonNullableString(global::System.Text.Json.JsonElement? obj) + { + if (!obj.HasValue) + { + throw new global::System.ArgumentNullException(); + } + + if (obj.Value.ValueKind == global::System.Text.Json.JsonValueKind.Null) + { + throw new global::System.ArgumentNullException(); + } + + return _iDParser.Parse(obj.Value.GetString()!); + } + + private global::System.String? Deserialize_String(global::System.Text.Json.JsonElement? obj) + { + if (!obj.HasValue) + { + return null; + } + + if (obj.Value.ValueKind == global::System.Text.Json.JsonValueKind.Null) + { + return null; + } + + return _stringParser.Parse(obj.Value.GetString()!); + } + + private global::StrawberryShake.EntityId? Update_IQ_Me_BestFriendEntity(global::StrawberryShake.IEntityStoreUpdateSession session, global::System.Text.Json.JsonElement? obj, global::System.Collections.Generic.ISet entityIds) + { + if (!obj.HasValue) + { + return null; + } + + if (obj.Value.ValueKind == global::System.Text.Json.JsonValueKind.Null) + { + return null; + } + + global::StrawberryShake.EntityId entityId = _idSerializer.Parse(obj.Value); + entityIds.Add(entityId); + if (entityId.Name.Equals("User", global::System.StringComparison.Ordinal)) + { + if (session.CurrentSnapshot.TryGetEntity(entityId, out global::Foo.Bar.State.UserEntity? entity)) + { + session.SetEntity(entityId, new global::Foo.Bar.State.UserEntity(Deserialize_NonNullableString(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "id")), Deserialize_String(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "name")), entity.BestFriend)); + } + else + { + session.SetEntity(entityId, new global::Foo.Bar.State.UserEntity(Deserialize_NonNullableString(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "id")), Deserialize_String(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "name")), default !)); + } + + return entityId; + } + + throw new global::System.NotSupportedException(); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultFromEntityTypeMapperGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class Q_Me_UserFromUserEntityMapper : global::StrawberryShake.IEntityMapper + { + private readonly global::StrawberryShake.IEntityStore _entityStore; + private readonly global::StrawberryShake.IEntityMapper _q_Me_BestFriend_UserFromUserEntityMapper; + public Q_Me_UserFromUserEntityMapper(global::StrawberryShake.IEntityStore entityStore, global::StrawberryShake.IEntityMapper q_Me_BestFriend_UserFromUserEntityMapper) + { + _entityStore = entityStore ?? throw new global::System.ArgumentNullException(nameof(entityStore)); + _q_Me_BestFriend_UserFromUserEntityMapper = q_Me_BestFriend_UserFromUserEntityMapper ?? throw new global::System.ArgumentNullException(nameof(q_Me_BestFriend_UserFromUserEntityMapper)); + } + + public Q_Me_User Map(global::Foo.Bar.State.UserEntity entity, global::StrawberryShake.IEntityStoreSnapshot? snapshot = null) + { + if (snapshot is null) + { + snapshot = _entityStore.CurrentSnapshot; + } + + return new Q_Me_User(entity.Id, entity.Name, MapIQ_Me_BestFriend(entity.BestFriend, snapshot)); + } + + private global::Foo.Bar.IQ_Me_BestFriend? MapIQ_Me_BestFriend(global::StrawberryShake.EntityId? entityId, global::StrawberryShake.IEntityStoreSnapshot snapshot) + { + if (entityId is null) + { + return null; + } + + if (entityId.Value.Name.Equals("User", global::System.StringComparison.Ordinal)) + { + return _q_Me_BestFriend_UserFromUserEntityMapper.Map(snapshot.GetEntity(entityId.Value) ?? throw new global::StrawberryShake.GraphQLClientException()); + } + + throw new global::System.NotSupportedException(); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultFromEntityTypeMapperGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class Q_Me_BestFriend_UserFromUserEntityMapper : global::StrawberryShake.IEntityMapper + { + private readonly global::StrawberryShake.IEntityStore _entityStore; + public Q_Me_BestFriend_UserFromUserEntityMapper(global::StrawberryShake.IEntityStore entityStore) + { + _entityStore = entityStore ?? throw new global::System.ArgumentNullException(nameof(entityStore)); + } + + public Q_Me_BestFriend_User Map(global::Foo.Bar.State.UserEntity entity, global::StrawberryShake.IEntityStoreSnapshot? snapshot = null) + { + if (snapshot is null) + { + snapshot = _entityStore.CurrentSnapshot; + } + + return new Q_Me_BestFriend_User(entity.Id, entity.Name); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.EntityIdFactoryGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class FooClientEntityIdFactory : global::StrawberryShake.IEntityIdSerializer + { + private static readonly global::System.Text.Json.JsonWriterOptions _options = new global::System.Text.Json.JsonWriterOptions() + { + Indented = false + }; + public global::StrawberryShake.EntityId Parse(global::System.Text.Json.JsonElement obj) + { + global::System.String __typename = obj.GetProperty("__typename").GetString()!; + return __typename switch + { + "User" => ParseUserEntityId(obj, __typename), + _ => throw new global::System.NotSupportedException()}; + } + + public global::System.String Format(global::StrawberryShake.EntityId entityId) + { + return entityId.Name switch + { + "User" => FormatUserEntityId(entityId), + _ => throw new global::System.NotSupportedException()}; + } + + private global::StrawberryShake.EntityId ParseUserEntityId(global::System.Text.Json.JsonElement obj, global::System.String type) + { + return new global::StrawberryShake.EntityId(type, obj.GetProperty("id").GetString()!); + } + + private global::System.String FormatUserEntityId(global::StrawberryShake.EntityId entityId) + { + using var writer = new global::StrawberryShake.Internal.ArrayWriter(); + using var jsonWriter = new global::System.Text.Json.Utf8JsonWriter(writer, _options); + jsonWriter.WriteStartObject(); + jsonWriter.WriteString("__typename", entityId.Name); + jsonWriter.WriteString("id", (global::System.String)entityId.Value); + jsonWriter.WriteEndObject(); + jsonWriter.Flush(); + return global::System.Text.Encoding.UTF8.GetString(writer.GetInternalBuffer(), 0, writer.Length); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.StoreAccessorGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class FooClientStoreAccessor : global::StrawberryShake.StoreAccessor + { + public FooClientStoreAccessor(global::StrawberryShake.IOperationStore operationStore, global::StrawberryShake.IEntityStore entityStore, global::StrawberryShake.IEntityIdSerializer entityIdSerializer, global::System.Collections.Generic.IEnumerable requestFactories, global::System.Collections.Generic.IEnumerable resultDataFactories) : base(operationStore, entityStore, entityIdSerializer, requestFactories, resultDataFactories) + { + } + } +} + +namespace Microsoft.Extensions.DependencyInjection +{ + // StrawberryShake.CodeGeneration.CSharp.Generators.DependencyInjectionGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public static partial class FooClientServiceCollectionExtensions + { + public static global::StrawberryShake.IClientBuilder AddFooClient(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::StrawberryShake.ExecutionStrategy strategy = global::StrawberryShake.ExecutionStrategy.NetworkOnly) + { + var serviceCollection = new global::Microsoft.Extensions.DependencyInjection.ServiceCollection(); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => + { + ConfigureClientDefault(sp, serviceCollection, strategy); + return new ClientServiceProvider(global::Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(serviceCollection)); + }); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => new global::Foo.Bar.State.FooClientStoreAccessor(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + return new global::StrawberryShake.ClientBuilder("FooClient", services, serviceCollection); + } + + private static global::Microsoft.Extensions.DependencyInjection.IServiceCollection ConfigureClientDefault(global::System.IServiceProvider parentServices, global::Microsoft.Extensions.DependencyInjection.ServiceCollection services, global::StrawberryShake.ExecutionStrategy strategy = global::StrawberryShake.ExecutionStrategy.NetworkOnly) + { + global::Microsoft.Extensions.DependencyInjection.Extensions.ServiceCollectionDescriptorExtensions.TryAddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.Extensions.ServiceCollectionDescriptorExtensions.TryAddSingleton(services, sp => new global::StrawberryShake.OperationStore(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => + { + var clientFactory = global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(parentServices); + return new global::StrawberryShake.Transport.Http.HttpConnection(() => clientFactory.CreateClient("FooClient")); + }); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::Foo.Bar.State.Q_Me_UserFromUserEntityMapper>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::Foo.Bar.State.Q_Me_BestFriend_UserFromUserEntityMapper>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => new global::StrawberryShake.Serialization.SerializerResolver(global::System.Linq.Enumerable.Concat(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(parentServices), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp)))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::Foo.Bar.State.QResultFactory>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::Foo.Bar.State.QBuilder>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton>(services, sp => new global::StrawberryShake.OperationExecutor(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp), () => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp), () => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp), strategy)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::StrawberryShake.Json.JsonResultPatcher>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)); + return services; + } + + private sealed class ClientServiceProvider : System.IServiceProvider, System.IDisposable + { + private readonly System.IServiceProvider _provider; + public ClientServiceProvider(System.IServiceProvider provider) + { + _provider = provider; + } + + public object? GetService(System.Type serviceType) + { + return _provider.GetService(serviceType); + } + + public void Dispose() + { + if (_provider is System.IDisposable d) + { + d.Dispose(); + } + } + } + } +} + + diff --git a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/DuplicateFragmentSpreadGeneratorTests.Generate_Should_Compile_When_Same_Fragment_Spread_Twice_On_Union_Member.snap b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/DuplicateFragmentSpreadGeneratorTests.Generate_Should_Compile_When_Same_Fragment_Spread_Twice_On_Union_Member.snap new file mode 100644 index 00000000000..01909566955 --- /dev/null +++ b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/DuplicateFragmentSpreadGeneratorTests.Generate_Should_Compile_When_Same_Fragment_Spread_Twice_On_Union_Member.snap @@ -0,0 +1,841 @@ +// ReSharper disable ArrangeObjectCreationWhenTypeEvident +// ReSharper disable BuiltInTypeReferenceStyle +// ReSharper disable ConvertToAutoProperty +// ReSharper disable InconsistentNaming +// ReSharper disable PartialTypeWithSinglePart +// ReSharper disable PreferConcreteValueOverDefault +// ReSharper disable RedundantNameQualifier +// ReSharper disable SuggestVarOrType_SimpleTypes +// ReSharper disable UnusedMember.Global +// ReSharper disable UnusedMethodReturnValue.Local +// ReSharper disable UnusedType.Global +// ReSharper disable UnusedVariable + +// FooClient + +// +#nullable enable annotations +#nullable disable warnings + +namespace Foo.Bar +{ + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultTypeGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QResult : global::System.IEquatable, IQResult + { + public QResult(global::Foo.Bar.IQ_Pet? pet) + { + Pet = pet; + } + + public global::Foo.Bar.IQ_Pet? Pet { get; } + + public virtual global::System.Boolean Equals(QResult? other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (other.GetType() != GetType()) + { + return false; + } + + return (((Pet is null && other.Pet is null) || Pet != null && Pet.Equals(other.Pet))); + } + + public override global::System.Boolean Equals(global::System.Object? obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != GetType()) + { + return false; + } + + return Equals((QResult)obj); + } + + public override global::System.Int32 GetHashCode() + { + unchecked + { + int hash = 5; + if (Pet != null) + { + hash ^= 397 * Pet.GetHashCode(); + } + + return hash; + } + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultTypeGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class Q_Pet_Dog : global::System.IEquatable, IQ_Pet_Dog + { + public Q_Pet_Dog(global::System.String? name) + { + Name = name; + } + + public global::System.String? Name { get; } + + public virtual global::System.Boolean Equals(Q_Pet_Dog? other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (other.GetType() != GetType()) + { + return false; + } + + return (((Name is null && other.Name is null) || Name != null && Name.Equals(other.Name))); + } + + public override global::System.Boolean Equals(global::System.Object? obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != GetType()) + { + return false; + } + + return Equals((Q_Pet_Dog)obj); + } + + public override global::System.Int32 GetHashCode() + { + unchecked + { + int hash = 5; + if (Name != null) + { + hash ^= 397 * Name.GetHashCode(); + } + + return hash; + } + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultTypeGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class Q_Pet_Cat : global::System.IEquatable, IQ_Pet_Cat + { + public Q_Pet_Cat() + { + } + + public virtual global::System.Boolean Equals(Q_Pet_Cat? other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (other.GetType() != GetType()) + { + return false; + } + + return true; + } + + public override global::System.Boolean Equals(global::System.Object? obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != GetType()) + { + return false; + } + + return Equals((Q_Pet_Cat)obj); + } + + public override global::System.Int32 GetHashCode() + { + unchecked + { + int hash = 5; + return hash; + } + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IQResult + { + public global::Foo.Bar.IQ_Pet? Pet { get; } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IQ_Pet + { + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IDF + { + public global::System.String? Name { get; } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IQ_Pet_Dog : IQ_Pet, IDF + { + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IQ_Pet_Cat : IQ_Pet + { + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.OperationDocumentGenerator + /// + /// Represents the operation service of the Q GraphQL operation + /// + /// query Q { + /// pet { + /// __typename + /// ...DF + /// ...DF + /// ... on Dog { + /// id + /// } + /// ... on Cat { + /// id + /// } + /// } + /// } + /// + /// fragment DF on Dog { + /// name + /// } + /// + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QQueryDocument : global::StrawberryShake.IDocument + { + private QQueryDocument() + { + } + + public static QQueryDocument Instance { get; } = new QQueryDocument(); + public global::StrawberryShake.OperationKind Kind => global::StrawberryShake.OperationKind.Query; + public global::System.ReadOnlySpan Body => "query Q { pet { __typename ...DF ...DF ... on Dog { id } ... on Cat { id } } } fragment DF on Dog { name }"u8; + public global::StrawberryShake.DocumentHash Hash { get; } = new global::StrawberryShake.DocumentHash("sha1Hash", "6de07ea4f0c8bf144ba023790250fbefc8e1918d"); + + public override global::System.String ToString() + { +#if NETCOREAPP3_1_OR_GREATER + return global::System.Text.Encoding.UTF8.GetString(Body); +#else + return global::System.Text.Encoding.UTF8.GetString(Body.ToArray()); +#endif + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.OperationServiceGenerator + /// + /// Represents the operation service of the Q GraphQL operation + /// + /// query Q { + /// pet { + /// __typename + /// ...DF + /// ...DF + /// ... on Dog { + /// id + /// } + /// ... on Cat { + /// id + /// } + /// } + /// } + /// + /// fragment DF on Dog { + /// name + /// } + /// + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QQuery : global::Foo.Bar.IQQuery + { + private readonly global::StrawberryShake.IOperationExecutor _operationExecutor; + private readonly global::System.Collections.Immutable.ImmutableArray> _configure = global::System.Collections.Immutable.ImmutableArray>.Empty; + public QQuery(global::StrawberryShake.IOperationExecutor operationExecutor) + { + _operationExecutor = operationExecutor ?? throw new global::System.ArgumentNullException(nameof(operationExecutor)); + } + + private QQuery(global::StrawberryShake.IOperationExecutor operationExecutor, global::System.Collections.Immutable.ImmutableArray> configure) + { + _operationExecutor = operationExecutor; + _configure = configure; + } + + global::System.Type global::StrawberryShake.IOperationRequestFactory.ResultType => typeof(IQResult); + + public global::Foo.Bar.IQQuery With(global::System.Action configure) + { + return new global::Foo.Bar.QQuery(_operationExecutor, _configure.Add(configure)); + } + + public global::Foo.Bar.IQQuery WithRequestUri(global::System.Uri requestUri) + { + return With(r => r.ContextData["StrawberryShake.Transport.Http.HttpConnection.RequestUri"] = requestUri); + } + + public global::Foo.Bar.IQQuery WithHttpClient(global::System.Net.Http.HttpClient httpClient) + { + return With(r => r.ContextData["StrawberryShake.Transport.Http.HttpConnection.HttpClient"] = httpClient); + } + + public async global::System.Threading.Tasks.Task> ExecuteAsync(global::System.Threading.CancellationToken cancellationToken = default) + { + var request = CreateRequest(); + foreach (var configure in _configure) + { + configure(request); + } + + return await _operationExecutor.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + } + + public global::System.IObservable> Watch(global::StrawberryShake.ExecutionStrategy? strategy = null) + { + var request = CreateRequest(); + return _operationExecutor.Watch(request, strategy); + } + + private global::StrawberryShake.OperationRequest CreateRequest() + { + return CreateRequest(null); + } + + private global::StrawberryShake.OperationRequest CreateRequest(global::System.Collections.Generic.IReadOnlyDictionary? variables) + { + return new global::StrawberryShake.OperationRequest(id: QQueryDocument.Instance.Hash.Value, name: "Q", document: QQueryDocument.Instance, strategy: global::StrawberryShake.RequestStrategy.Default); + } + + global::StrawberryShake.OperationRequest global::StrawberryShake.IOperationRequestFactory.Create(global::System.Collections.Generic.IReadOnlyDictionary? variables) + { + return CreateRequest(); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.OperationServiceInterfaceGenerator + /// + /// Represents the operation service of the Q GraphQL operation + /// + /// query Q { + /// pet { + /// __typename + /// ...DF + /// ...DF + /// ... on Dog { + /// id + /// } + /// ... on Cat { + /// id + /// } + /// } + /// } + /// + /// fragment DF on Dog { + /// name + /// } + /// + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IQQuery : global::StrawberryShake.IOperationRequestFactory + { + global::Foo.Bar.IQQuery With(global::System.Action configure); + global::Foo.Bar.IQQuery WithRequestUri(global::System.Uri requestUri); + global::Foo.Bar.IQQuery WithHttpClient(global::System.Net.Http.HttpClient httpClient); + global::System.Threading.Tasks.Task> ExecuteAsync(global::System.Threading.CancellationToken cancellationToken = default); + global::System.IObservable> Watch(global::StrawberryShake.ExecutionStrategy? strategy = null); + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ClientGenerator + /// + /// Represents the FooClient GraphQL client + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class FooClient : global::Foo.Bar.IFooClient + { + private readonly global::Foo.Bar.IQQuery _q; + public FooClient(global::Foo.Bar.IQQuery q) + { + _q = q ?? throw new global::System.ArgumentNullException(nameof(q)); + } + + public static global::System.String ClientName => "FooClient"; + public global::Foo.Bar.IQQuery Q => _q; + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ClientInterfaceGenerator + /// + /// Represents the FooClient GraphQL client + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IFooClient + { + global::Foo.Bar.IQQuery Q { get; } + } +} + +namespace Foo.Bar.State +{ + // StrawberryShake.CodeGeneration.CSharp.Generators.EntityTypeGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "0.0.0.0")] + public partial class DogEntity + { + public DogEntity(global::System.String? name = default !) + { + Name = name; + } + + public global::System.String? Name { get; } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.EntityTypeGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "0.0.0.0")] + public partial class CatEntity + { + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultDataFactoryGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QResultFactory : global::StrawberryShake.IOperationResultDataFactory + { + private readonly global::StrawberryShake.IEntityStore _entityStore; + private readonly global::StrawberryShake.IEntityMapper _q_Pet_DogFromDogEntityMapper; + private readonly global::StrawberryShake.IEntityMapper _q_Pet_CatFromCatEntityMapper; + public QResultFactory(global::StrawberryShake.IEntityStore entityStore, global::StrawberryShake.IEntityMapper q_Pet_DogFromDogEntityMapper, global::StrawberryShake.IEntityMapper q_Pet_CatFromCatEntityMapper) + { + _entityStore = entityStore ?? throw new global::System.ArgumentNullException(nameof(entityStore)); + _q_Pet_DogFromDogEntityMapper = q_Pet_DogFromDogEntityMapper ?? throw new global::System.ArgumentNullException(nameof(q_Pet_DogFromDogEntityMapper)); + _q_Pet_CatFromCatEntityMapper = q_Pet_CatFromCatEntityMapper ?? throw new global::System.ArgumentNullException(nameof(q_Pet_CatFromCatEntityMapper)); + } + + global::System.Type global::StrawberryShake.IOperationResultDataFactory.ResultType => typeof(global::Foo.Bar.IQResult); + + public QResult Create(global::StrawberryShake.IOperationResultDataInfo dataInfo, global::StrawberryShake.IEntityStoreSnapshot? snapshot = null) + { + if (snapshot is null) + { + snapshot = _entityStore.CurrentSnapshot; + } + + if (dataInfo is QResultInfo info) + { + return new QResult(MapIQ_Pet(info.Pet, snapshot)); + } + + throw new global::System.ArgumentException("QResultInfo expected."); + } + + private global::Foo.Bar.IQ_Pet? MapIQ_Pet(global::StrawberryShake.EntityId? entityId, global::StrawberryShake.IEntityStoreSnapshot snapshot) + { + if (entityId is null) + { + return null; + } + + if (entityId.Value.Name.Equals("Dog", global::System.StringComparison.Ordinal)) + { + return _q_Pet_DogFromDogEntityMapper.Map(snapshot.GetEntity(entityId.Value) ?? throw new global::StrawberryShake.GraphQLClientException()); + } + + if (entityId.Value.Name.Equals("Cat", global::System.StringComparison.Ordinal)) + { + return _q_Pet_CatFromCatEntityMapper.Map(snapshot.GetEntity(entityId.Value) ?? throw new global::StrawberryShake.GraphQLClientException()); + } + + throw new global::System.NotSupportedException(); + } + + global::System.Object global::StrawberryShake.IOperationResultDataFactory.Create(global::StrawberryShake.IOperationResultDataInfo dataInfo, global::StrawberryShake.IEntityStoreSnapshot? snapshot) + { + return Create(dataInfo, snapshot); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInfoGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QResultInfo : global::StrawberryShake.IOperationResultDataInfo + { + private readonly global::System.Collections.Generic.IReadOnlyCollection _entityIds; + private readonly global::System.UInt64 _version; + public QResultInfo(global::StrawberryShake.EntityId? pet, global::System.Collections.Generic.IReadOnlyCollection entityIds, global::System.UInt64 version) + { + Pet = pet; + _entityIds = entityIds ?? throw new global::System.ArgumentNullException(nameof(entityIds)); + _version = version; + } + + public global::StrawberryShake.EntityId? Pet { get; } + public global::System.Collections.Generic.IReadOnlyCollection EntityIds => _entityIds; + public global::System.UInt64 Version => _version; + + public global::StrawberryShake.IOperationResultDataInfo WithVersion(global::System.UInt64 version) + { + return new QResultInfo(Pet, _entityIds, version); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.JsonResultBuilderGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QBuilder : global::StrawberryShake.OperationResultBuilder + { + private readonly global::StrawberryShake.IEntityStore _entityStore; + private readonly global::StrawberryShake.IEntityIdSerializer _idSerializer; + private readonly global::StrawberryShake.Serialization.ILeafValueParser _stringParser; + public QBuilder(global::StrawberryShake.IEntityStore entityStore, global::StrawberryShake.IEntityIdSerializer idSerializer, global::StrawberryShake.IOperationResultDataFactory resultDataFactory, global::StrawberryShake.Serialization.ISerializerResolver serializerResolver) + { + _entityStore = entityStore ?? throw new global::System.ArgumentNullException(nameof(entityStore)); + _idSerializer = idSerializer ?? throw new global::System.ArgumentNullException(nameof(idSerializer)); + ResultDataFactory = resultDataFactory ?? throw new global::System.ArgumentNullException(nameof(resultDataFactory)); + _stringParser = serializerResolver.GetLeafValueParser("String") ?? throw new global::System.ArgumentException("No serializer for type `String` found."); + } + + protected override global::StrawberryShake.IOperationResultDataFactory ResultDataFactory { get; } + + protected override global::StrawberryShake.IOperationResultDataInfo BuildData(global::System.Text.Json.JsonElement obj) + { + var entityIds = new global::System.Collections.Generic.HashSet(); + global::StrawberryShake.IEntityStoreSnapshot snapshot = default !; + global::StrawberryShake.EntityId? petId = default !; + _entityStore.Update(session => + { + petId = Update_IQ_PetEntity(session, global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "pet"), entityIds); + snapshot = session.CurrentSnapshot; + }); + return new QResultInfo(petId, entityIds, snapshot.Version); + } + + private global::StrawberryShake.EntityId? Update_IQ_PetEntity(global::StrawberryShake.IEntityStoreUpdateSession session, global::System.Text.Json.JsonElement? obj, global::System.Collections.Generic.ISet entityIds) + { + if (!obj.HasValue) + { + return null; + } + + if (obj.Value.ValueKind == global::System.Text.Json.JsonValueKind.Null) + { + return null; + } + + global::StrawberryShake.EntityId entityId = _idSerializer.Parse(obj.Value); + entityIds.Add(entityId); + if (entityId.Name.Equals("Dog", global::System.StringComparison.Ordinal)) + { + if (session.CurrentSnapshot.TryGetEntity(entityId, out global::Foo.Bar.State.DogEntity? entity)) + { + session.SetEntity(entityId, new global::Foo.Bar.State.DogEntity(Deserialize_String(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "name")))); + } + else + { + session.SetEntity(entityId, new global::Foo.Bar.State.DogEntity(Deserialize_String(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "name")))); + } + + return entityId; + } + + if (entityId.Name.Equals("Cat", global::System.StringComparison.Ordinal)) + { + if (session.CurrentSnapshot.TryGetEntity(entityId, out global::Foo.Bar.State.CatEntity? entity)) + { + session.SetEntity(entityId, new global::Foo.Bar.State.CatEntity()); + } + else + { + session.SetEntity(entityId, new global::Foo.Bar.State.CatEntity()); + } + + return entityId; + } + + throw new global::System.NotSupportedException(); + } + + private global::System.String? Deserialize_String(global::System.Text.Json.JsonElement? obj) + { + if (!obj.HasValue) + { + return null; + } + + if (obj.Value.ValueKind == global::System.Text.Json.JsonValueKind.Null) + { + return null; + } + + return _stringParser.Parse(obj.Value.GetString()!); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultFromEntityTypeMapperGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class Q_Pet_DogFromDogEntityMapper : global::StrawberryShake.IEntityMapper + { + private readonly global::StrawberryShake.IEntityStore _entityStore; + public Q_Pet_DogFromDogEntityMapper(global::StrawberryShake.IEntityStore entityStore) + { + _entityStore = entityStore ?? throw new global::System.ArgumentNullException(nameof(entityStore)); + } + + public Q_Pet_Dog Map(global::Foo.Bar.State.DogEntity entity, global::StrawberryShake.IEntityStoreSnapshot? snapshot = null) + { + if (snapshot is null) + { + snapshot = _entityStore.CurrentSnapshot; + } + + return new Q_Pet_Dog(entity.Name); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultFromEntityTypeMapperGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class Q_Pet_CatFromCatEntityMapper : global::StrawberryShake.IEntityMapper + { + private readonly global::StrawberryShake.IEntityStore _entityStore; + public Q_Pet_CatFromCatEntityMapper(global::StrawberryShake.IEntityStore entityStore) + { + _entityStore = entityStore ?? throw new global::System.ArgumentNullException(nameof(entityStore)); + } + + public Q_Pet_Cat Map(global::Foo.Bar.State.CatEntity entity, global::StrawberryShake.IEntityStoreSnapshot? snapshot = null) + { + if (snapshot is null) + { + snapshot = _entityStore.CurrentSnapshot; + } + + return new Q_Pet_Cat(); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.EntityIdFactoryGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class FooClientEntityIdFactory : global::StrawberryShake.IEntityIdSerializer + { + private static readonly global::System.Text.Json.JsonWriterOptions _options = new global::System.Text.Json.JsonWriterOptions() + { + Indented = false + }; + public global::StrawberryShake.EntityId Parse(global::System.Text.Json.JsonElement obj) + { + global::System.String __typename = obj.GetProperty("__typename").GetString()!; + return __typename switch + { + "Dog" => ParseDogEntityId(obj, __typename), + "Cat" => ParseCatEntityId(obj, __typename), + _ => throw new global::System.NotSupportedException()}; + } + + public global::System.String Format(global::StrawberryShake.EntityId entityId) + { + return entityId.Name switch + { + "Dog" => FormatDogEntityId(entityId), + "Cat" => FormatCatEntityId(entityId), + _ => throw new global::System.NotSupportedException()}; + } + + private global::StrawberryShake.EntityId ParseDogEntityId(global::System.Text.Json.JsonElement obj, global::System.String type) + { + return new global::StrawberryShake.EntityId(type, obj.GetProperty("id").GetString()!); + } + + private global::System.String FormatDogEntityId(global::StrawberryShake.EntityId entityId) + { + using var writer = new global::StrawberryShake.Internal.ArrayWriter(); + using var jsonWriter = new global::System.Text.Json.Utf8JsonWriter(writer, _options); + jsonWriter.WriteStartObject(); + jsonWriter.WriteString("__typename", entityId.Name); + jsonWriter.WriteString("id", (global::System.String)entityId.Value); + jsonWriter.WriteEndObject(); + jsonWriter.Flush(); + return global::System.Text.Encoding.UTF8.GetString(writer.GetInternalBuffer(), 0, writer.Length); + } + + private global::StrawberryShake.EntityId ParseCatEntityId(global::System.Text.Json.JsonElement obj, global::System.String type) + { + return new global::StrawberryShake.EntityId(type, obj.GetProperty("id").GetString()!); + } + + private global::System.String FormatCatEntityId(global::StrawberryShake.EntityId entityId) + { + using var writer = new global::StrawberryShake.Internal.ArrayWriter(); + using var jsonWriter = new global::System.Text.Json.Utf8JsonWriter(writer, _options); + jsonWriter.WriteStartObject(); + jsonWriter.WriteString("__typename", entityId.Name); + jsonWriter.WriteString("id", (global::System.String)entityId.Value); + jsonWriter.WriteEndObject(); + jsonWriter.Flush(); + return global::System.Text.Encoding.UTF8.GetString(writer.GetInternalBuffer(), 0, writer.Length); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.StoreAccessorGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class FooClientStoreAccessor : global::StrawberryShake.StoreAccessor + { + public FooClientStoreAccessor(global::StrawberryShake.IOperationStore operationStore, global::StrawberryShake.IEntityStore entityStore, global::StrawberryShake.IEntityIdSerializer entityIdSerializer, global::System.Collections.Generic.IEnumerable requestFactories, global::System.Collections.Generic.IEnumerable resultDataFactories) : base(operationStore, entityStore, entityIdSerializer, requestFactories, resultDataFactories) + { + } + } +} + +namespace Microsoft.Extensions.DependencyInjection +{ + // StrawberryShake.CodeGeneration.CSharp.Generators.DependencyInjectionGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public static partial class FooClientServiceCollectionExtensions + { + public static global::StrawberryShake.IClientBuilder AddFooClient(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::StrawberryShake.ExecutionStrategy strategy = global::StrawberryShake.ExecutionStrategy.NetworkOnly) + { + var serviceCollection = new global::Microsoft.Extensions.DependencyInjection.ServiceCollection(); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => + { + ConfigureClientDefault(sp, serviceCollection, strategy); + return new ClientServiceProvider(global::Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(serviceCollection)); + }); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => new global::Foo.Bar.State.FooClientStoreAccessor(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + return new global::StrawberryShake.ClientBuilder("FooClient", services, serviceCollection); + } + + private static global::Microsoft.Extensions.DependencyInjection.IServiceCollection ConfigureClientDefault(global::System.IServiceProvider parentServices, global::Microsoft.Extensions.DependencyInjection.ServiceCollection services, global::StrawberryShake.ExecutionStrategy strategy = global::StrawberryShake.ExecutionStrategy.NetworkOnly) + { + global::Microsoft.Extensions.DependencyInjection.Extensions.ServiceCollectionDescriptorExtensions.TryAddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.Extensions.ServiceCollectionDescriptorExtensions.TryAddSingleton(services, sp => new global::StrawberryShake.OperationStore(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => + { + var clientFactory = global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(parentServices); + return new global::StrawberryShake.Transport.Http.HttpConnection(() => clientFactory.CreateClient("FooClient")); + }); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::Foo.Bar.State.Q_Pet_DogFromDogEntityMapper>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::Foo.Bar.State.Q_Pet_CatFromCatEntityMapper>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => new global::StrawberryShake.Serialization.SerializerResolver(global::System.Linq.Enumerable.Concat(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(parentServices), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp)))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::Foo.Bar.State.QResultFactory>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::Foo.Bar.State.QBuilder>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton>(services, sp => new global::StrawberryShake.OperationExecutor(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp), () => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp), () => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp), strategy)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::StrawberryShake.Json.JsonResultPatcher>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)); + return services; + } + + private sealed class ClientServiceProvider : System.IServiceProvider, System.IDisposable + { + private readonly System.IServiceProvider _provider; + public ClientServiceProvider(System.IServiceProvider provider) + { + _provider = provider; + } + + public object? GetService(System.Type serviceType) + { + return _provider.GetService(serviceType); + } + + public void Dispose() + { + if (_provider is System.IDisposable d) + { + d.Dispose(); + } + } + } + } +} + + diff --git a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/DuplicateFragmentSpreadGeneratorTests.Generate_Should_Compile_When_Same_Interface_Fragment_Spread_Twice.snap b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/DuplicateFragmentSpreadGeneratorTests.Generate_Should_Compile_When_Same_Interface_Fragment_Spread_Twice.snap new file mode 100644 index 00000000000..2841ff461ae --- /dev/null +++ b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/DuplicateFragmentSpreadGeneratorTests.Generate_Should_Compile_When_Same_Interface_Fragment_Spread_Twice.snap @@ -0,0 +1,696 @@ +// ReSharper disable ArrangeObjectCreationWhenTypeEvident +// ReSharper disable BuiltInTypeReferenceStyle +// ReSharper disable ConvertToAutoProperty +// ReSharper disable InconsistentNaming +// ReSharper disable PartialTypeWithSinglePart +// ReSharper disable PreferConcreteValueOverDefault +// ReSharper disable RedundantNameQualifier +// ReSharper disable SuggestVarOrType_SimpleTypes +// ReSharper disable UnusedMember.Global +// ReSharper disable UnusedMethodReturnValue.Local +// ReSharper disable UnusedType.Global +// ReSharper disable UnusedVariable + +// FooClient + +// +#nullable enable annotations +#nullable disable warnings + +namespace Foo.Bar +{ + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultTypeGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QResult : global::System.IEquatable, IQResult + { + public QResult(global::Foo.Bar.IQ_Node? node) + { + Node = node; + } + + public global::Foo.Bar.IQ_Node? Node { get; } + + public virtual global::System.Boolean Equals(QResult? other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (other.GetType() != GetType()) + { + return false; + } + + return (((Node is null && other.Node is null) || Node != null && Node.Equals(other.Node))); + } + + public override global::System.Boolean Equals(global::System.Object? obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != GetType()) + { + return false; + } + + return Equals((QResult)obj); + } + + public override global::System.Int32 GetHashCode() + { + unchecked + { + int hash = 5; + if (Node != null) + { + hash ^= 397 * Node.GetHashCode(); + } + + return hash; + } + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultTypeGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class Q_Node_User : global::System.IEquatable, IQ_Node_User + { + public Q_Node_User(global::System.String id) + { + Id = id; + } + + public global::System.String Id { get; } + + public virtual global::System.Boolean Equals(Q_Node_User? other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (other.GetType() != GetType()) + { + return false; + } + + return (Id.Equals(other.Id)); + } + + public override global::System.Boolean Equals(global::System.Object? obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != GetType()) + { + return false; + } + + return Equals((Q_Node_User)obj); + } + + public override global::System.Int32 GetHashCode() + { + unchecked + { + int hash = 5; + hash ^= 397 * Id.GetHashCode(); + return hash; + } + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IQResult + { + public global::Foo.Bar.IQ_Node? Node { get; } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface INF + { + public global::System.String Id { get; } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IQ_Node : INF + { + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IQ_Node_User : IQ_Node + { + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.OperationDocumentGenerator + /// + /// Represents the operation service of the Q GraphQL operation + /// + /// query Q { + /// node(id: "1") { + /// __typename + /// ...NF + /// ...NF + /// ... on User { + /// id + /// } + /// } + /// } + /// + /// fragment NF on Node { + /// id + /// } + /// + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QQueryDocument : global::StrawberryShake.IDocument + { + private QQueryDocument() + { + } + + public static QQueryDocument Instance { get; } = new QQueryDocument(); + public global::StrawberryShake.OperationKind Kind => global::StrawberryShake.OperationKind.Query; + public global::System.ReadOnlySpan Body => "query Q { node(id: \"1\") { __typename ...NF ...NF ... on User { id } } } fragment NF on Node { id }"u8; + public global::StrawberryShake.DocumentHash Hash { get; } = new global::StrawberryShake.DocumentHash("sha1Hash", "05f3da2fff3b0a1e4138ba461ebec1075e2f2373"); + + public override global::System.String ToString() + { +#if NETCOREAPP3_1_OR_GREATER + return global::System.Text.Encoding.UTF8.GetString(Body); +#else + return global::System.Text.Encoding.UTF8.GetString(Body.ToArray()); +#endif + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.OperationServiceGenerator + /// + /// Represents the operation service of the Q GraphQL operation + /// + /// query Q { + /// node(id: "1") { + /// __typename + /// ...NF + /// ...NF + /// ... on User { + /// id + /// } + /// } + /// } + /// + /// fragment NF on Node { + /// id + /// } + /// + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QQuery : global::Foo.Bar.IQQuery + { + private readonly global::StrawberryShake.IOperationExecutor _operationExecutor; + private readonly global::System.Collections.Immutable.ImmutableArray> _configure = global::System.Collections.Immutable.ImmutableArray>.Empty; + public QQuery(global::StrawberryShake.IOperationExecutor operationExecutor) + { + _operationExecutor = operationExecutor ?? throw new global::System.ArgumentNullException(nameof(operationExecutor)); + } + + private QQuery(global::StrawberryShake.IOperationExecutor operationExecutor, global::System.Collections.Immutable.ImmutableArray> configure) + { + _operationExecutor = operationExecutor; + _configure = configure; + } + + global::System.Type global::StrawberryShake.IOperationRequestFactory.ResultType => typeof(IQResult); + + public global::Foo.Bar.IQQuery With(global::System.Action configure) + { + return new global::Foo.Bar.QQuery(_operationExecutor, _configure.Add(configure)); + } + + public global::Foo.Bar.IQQuery WithRequestUri(global::System.Uri requestUri) + { + return With(r => r.ContextData["StrawberryShake.Transport.Http.HttpConnection.RequestUri"] = requestUri); + } + + public global::Foo.Bar.IQQuery WithHttpClient(global::System.Net.Http.HttpClient httpClient) + { + return With(r => r.ContextData["StrawberryShake.Transport.Http.HttpConnection.HttpClient"] = httpClient); + } + + public async global::System.Threading.Tasks.Task> ExecuteAsync(global::System.Threading.CancellationToken cancellationToken = default) + { + var request = CreateRequest(); + foreach (var configure in _configure) + { + configure(request); + } + + return await _operationExecutor.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + } + + public global::System.IObservable> Watch(global::StrawberryShake.ExecutionStrategy? strategy = null) + { + var request = CreateRequest(); + return _operationExecutor.Watch(request, strategy); + } + + private global::StrawberryShake.OperationRequest CreateRequest() + { + return CreateRequest(null); + } + + private global::StrawberryShake.OperationRequest CreateRequest(global::System.Collections.Generic.IReadOnlyDictionary? variables) + { + return new global::StrawberryShake.OperationRequest(id: QQueryDocument.Instance.Hash.Value, name: "Q", document: QQueryDocument.Instance, strategy: global::StrawberryShake.RequestStrategy.Default); + } + + global::StrawberryShake.OperationRequest global::StrawberryShake.IOperationRequestFactory.Create(global::System.Collections.Generic.IReadOnlyDictionary? variables) + { + return CreateRequest(); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.OperationServiceInterfaceGenerator + /// + /// Represents the operation service of the Q GraphQL operation + /// + /// query Q { + /// node(id: "1") { + /// __typename + /// ...NF + /// ...NF + /// ... on User { + /// id + /// } + /// } + /// } + /// + /// fragment NF on Node { + /// id + /// } + /// + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IQQuery : global::StrawberryShake.IOperationRequestFactory + { + global::Foo.Bar.IQQuery With(global::System.Action configure); + global::Foo.Bar.IQQuery WithRequestUri(global::System.Uri requestUri); + global::Foo.Bar.IQQuery WithHttpClient(global::System.Net.Http.HttpClient httpClient); + global::System.Threading.Tasks.Task> ExecuteAsync(global::System.Threading.CancellationToken cancellationToken = default); + global::System.IObservable> Watch(global::StrawberryShake.ExecutionStrategy? strategy = null); + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ClientGenerator + /// + /// Represents the FooClient GraphQL client + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class FooClient : global::Foo.Bar.IFooClient + { + private readonly global::Foo.Bar.IQQuery _q; + public FooClient(global::Foo.Bar.IQQuery q) + { + _q = q ?? throw new global::System.ArgumentNullException(nameof(q)); + } + + public static global::System.String ClientName => "FooClient"; + public global::Foo.Bar.IQQuery Q => _q; + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ClientInterfaceGenerator + /// + /// Represents the FooClient GraphQL client + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IFooClient + { + global::Foo.Bar.IQQuery Q { get; } + } +} + +namespace Foo.Bar.State +{ + // StrawberryShake.CodeGeneration.CSharp.Generators.EntityTypeGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "0.0.0.0")] + public partial class UserEntity + { + public UserEntity(global::System.String id = default !) + { + Id = id; + } + + public global::System.String Id { get; } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultDataFactoryGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QResultFactory : global::StrawberryShake.IOperationResultDataFactory + { + private readonly global::StrawberryShake.IEntityStore _entityStore; + private readonly global::StrawberryShake.IEntityMapper _q_Node_UserFromUserEntityMapper; + public QResultFactory(global::StrawberryShake.IEntityStore entityStore, global::StrawberryShake.IEntityMapper q_Node_UserFromUserEntityMapper) + { + _entityStore = entityStore ?? throw new global::System.ArgumentNullException(nameof(entityStore)); + _q_Node_UserFromUserEntityMapper = q_Node_UserFromUserEntityMapper ?? throw new global::System.ArgumentNullException(nameof(q_Node_UserFromUserEntityMapper)); + } + + global::System.Type global::StrawberryShake.IOperationResultDataFactory.ResultType => typeof(global::Foo.Bar.IQResult); + + public QResult Create(global::StrawberryShake.IOperationResultDataInfo dataInfo, global::StrawberryShake.IEntityStoreSnapshot? snapshot = null) + { + if (snapshot is null) + { + snapshot = _entityStore.CurrentSnapshot; + } + + if (dataInfo is QResultInfo info) + { + return new QResult(MapIQ_Node(info.Node, snapshot)); + } + + throw new global::System.ArgumentException("QResultInfo expected."); + } + + private global::Foo.Bar.IQ_Node? MapIQ_Node(global::StrawberryShake.EntityId? entityId, global::StrawberryShake.IEntityStoreSnapshot snapshot) + { + if (entityId is null) + { + return null; + } + + if (entityId.Value.Name.Equals("User", global::System.StringComparison.Ordinal)) + { + return _q_Node_UserFromUserEntityMapper.Map(snapshot.GetEntity(entityId.Value) ?? throw new global::StrawberryShake.GraphQLClientException()); + } + + throw new global::System.NotSupportedException(); + } + + global::System.Object global::StrawberryShake.IOperationResultDataFactory.Create(global::StrawberryShake.IOperationResultDataInfo dataInfo, global::StrawberryShake.IEntityStoreSnapshot? snapshot) + { + return Create(dataInfo, snapshot); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInfoGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QResultInfo : global::StrawberryShake.IOperationResultDataInfo + { + private readonly global::System.Collections.Generic.IReadOnlyCollection _entityIds; + private readonly global::System.UInt64 _version; + public QResultInfo(global::StrawberryShake.EntityId? node, global::System.Collections.Generic.IReadOnlyCollection entityIds, global::System.UInt64 version) + { + Node = node; + _entityIds = entityIds ?? throw new global::System.ArgumentNullException(nameof(entityIds)); + _version = version; + } + + public global::StrawberryShake.EntityId? Node { get; } + public global::System.Collections.Generic.IReadOnlyCollection EntityIds => _entityIds; + public global::System.UInt64 Version => _version; + + public global::StrawberryShake.IOperationResultDataInfo WithVersion(global::System.UInt64 version) + { + return new QResultInfo(Node, _entityIds, version); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.JsonResultBuilderGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QBuilder : global::StrawberryShake.OperationResultBuilder + { + private readonly global::StrawberryShake.IEntityStore _entityStore; + private readonly global::StrawberryShake.IEntityIdSerializer _idSerializer; + private readonly global::StrawberryShake.Serialization.ILeafValueParser _iDParser; + public QBuilder(global::StrawberryShake.IEntityStore entityStore, global::StrawberryShake.IEntityIdSerializer idSerializer, global::StrawberryShake.IOperationResultDataFactory resultDataFactory, global::StrawberryShake.Serialization.ISerializerResolver serializerResolver) + { + _entityStore = entityStore ?? throw new global::System.ArgumentNullException(nameof(entityStore)); + _idSerializer = idSerializer ?? throw new global::System.ArgumentNullException(nameof(idSerializer)); + ResultDataFactory = resultDataFactory ?? throw new global::System.ArgumentNullException(nameof(resultDataFactory)); + _iDParser = serializerResolver.GetLeafValueParser("ID") ?? throw new global::System.ArgumentException("No serializer for type `ID` found."); + } + + protected override global::StrawberryShake.IOperationResultDataFactory ResultDataFactory { get; } + + protected override global::StrawberryShake.IOperationResultDataInfo BuildData(global::System.Text.Json.JsonElement obj) + { + var entityIds = new global::System.Collections.Generic.HashSet(); + global::StrawberryShake.IEntityStoreSnapshot snapshot = default !; + global::StrawberryShake.EntityId? nodeId = default !; + _entityStore.Update(session => + { + nodeId = Update_IQ_NodeEntity(session, global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "node"), entityIds); + snapshot = session.CurrentSnapshot; + }); + return new QResultInfo(nodeId, entityIds, snapshot.Version); + } + + private global::StrawberryShake.EntityId? Update_IQ_NodeEntity(global::StrawberryShake.IEntityStoreUpdateSession session, global::System.Text.Json.JsonElement? obj, global::System.Collections.Generic.ISet entityIds) + { + if (!obj.HasValue) + { + return null; + } + + if (obj.Value.ValueKind == global::System.Text.Json.JsonValueKind.Null) + { + return null; + } + + global::StrawberryShake.EntityId entityId = _idSerializer.Parse(obj.Value); + entityIds.Add(entityId); + if (entityId.Name.Equals("User", global::System.StringComparison.Ordinal)) + { + if (session.CurrentSnapshot.TryGetEntity(entityId, out global::Foo.Bar.State.UserEntity? entity)) + { + session.SetEntity(entityId, new global::Foo.Bar.State.UserEntity(Deserialize_NonNullableString(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "id")))); + } + else + { + session.SetEntity(entityId, new global::Foo.Bar.State.UserEntity(Deserialize_NonNullableString(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "id")))); + } + + return entityId; + } + + throw new global::System.NotSupportedException(); + } + + private global::System.String Deserialize_NonNullableString(global::System.Text.Json.JsonElement? obj) + { + if (!obj.HasValue) + { + throw new global::System.ArgumentNullException(); + } + + if (obj.Value.ValueKind == global::System.Text.Json.JsonValueKind.Null) + { + throw new global::System.ArgumentNullException(); + } + + return _iDParser.Parse(obj.Value.GetString()!); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultFromEntityTypeMapperGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class Q_Node_UserFromUserEntityMapper : global::StrawberryShake.IEntityMapper + { + private readonly global::StrawberryShake.IEntityStore _entityStore; + public Q_Node_UserFromUserEntityMapper(global::StrawberryShake.IEntityStore entityStore) + { + _entityStore = entityStore ?? throw new global::System.ArgumentNullException(nameof(entityStore)); + } + + public Q_Node_User Map(global::Foo.Bar.State.UserEntity entity, global::StrawberryShake.IEntityStoreSnapshot? snapshot = null) + { + if (snapshot is null) + { + snapshot = _entityStore.CurrentSnapshot; + } + + return new Q_Node_User(entity.Id); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.EntityIdFactoryGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class FooClientEntityIdFactory : global::StrawberryShake.IEntityIdSerializer + { + private static readonly global::System.Text.Json.JsonWriterOptions _options = new global::System.Text.Json.JsonWriterOptions() + { + Indented = false + }; + public global::StrawberryShake.EntityId Parse(global::System.Text.Json.JsonElement obj) + { + global::System.String __typename = obj.GetProperty("__typename").GetString()!; + return __typename switch + { + "User" => ParseUserEntityId(obj, __typename), + _ => throw new global::System.NotSupportedException()}; + } + + public global::System.String Format(global::StrawberryShake.EntityId entityId) + { + return entityId.Name switch + { + "User" => FormatUserEntityId(entityId), + _ => throw new global::System.NotSupportedException()}; + } + + private global::StrawberryShake.EntityId ParseUserEntityId(global::System.Text.Json.JsonElement obj, global::System.String type) + { + return new global::StrawberryShake.EntityId(type, obj.GetProperty("id").GetString()!); + } + + private global::System.String FormatUserEntityId(global::StrawberryShake.EntityId entityId) + { + using var writer = new global::StrawberryShake.Internal.ArrayWriter(); + using var jsonWriter = new global::System.Text.Json.Utf8JsonWriter(writer, _options); + jsonWriter.WriteStartObject(); + jsonWriter.WriteString("__typename", entityId.Name); + jsonWriter.WriteString("id", (global::System.String)entityId.Value); + jsonWriter.WriteEndObject(); + jsonWriter.Flush(); + return global::System.Text.Encoding.UTF8.GetString(writer.GetInternalBuffer(), 0, writer.Length); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.StoreAccessorGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class FooClientStoreAccessor : global::StrawberryShake.StoreAccessor + { + public FooClientStoreAccessor(global::StrawberryShake.IOperationStore operationStore, global::StrawberryShake.IEntityStore entityStore, global::StrawberryShake.IEntityIdSerializer entityIdSerializer, global::System.Collections.Generic.IEnumerable requestFactories, global::System.Collections.Generic.IEnumerable resultDataFactories) : base(operationStore, entityStore, entityIdSerializer, requestFactories, resultDataFactories) + { + } + } +} + +namespace Microsoft.Extensions.DependencyInjection +{ + // StrawberryShake.CodeGeneration.CSharp.Generators.DependencyInjectionGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public static partial class FooClientServiceCollectionExtensions + { + public static global::StrawberryShake.IClientBuilder AddFooClient(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::StrawberryShake.ExecutionStrategy strategy = global::StrawberryShake.ExecutionStrategy.NetworkOnly) + { + var serviceCollection = new global::Microsoft.Extensions.DependencyInjection.ServiceCollection(); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => + { + ConfigureClientDefault(sp, serviceCollection, strategy); + return new ClientServiceProvider(global::Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(serviceCollection)); + }); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => new global::Foo.Bar.State.FooClientStoreAccessor(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + return new global::StrawberryShake.ClientBuilder("FooClient", services, serviceCollection); + } + + private static global::Microsoft.Extensions.DependencyInjection.IServiceCollection ConfigureClientDefault(global::System.IServiceProvider parentServices, global::Microsoft.Extensions.DependencyInjection.ServiceCollection services, global::StrawberryShake.ExecutionStrategy strategy = global::StrawberryShake.ExecutionStrategy.NetworkOnly) + { + global::Microsoft.Extensions.DependencyInjection.Extensions.ServiceCollectionDescriptorExtensions.TryAddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.Extensions.ServiceCollectionDescriptorExtensions.TryAddSingleton(services, sp => new global::StrawberryShake.OperationStore(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => + { + var clientFactory = global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(parentServices); + return new global::StrawberryShake.Transport.Http.HttpConnection(() => clientFactory.CreateClient("FooClient")); + }); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::Foo.Bar.State.Q_Node_UserFromUserEntityMapper>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => new global::StrawberryShake.Serialization.SerializerResolver(global::System.Linq.Enumerable.Concat(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(parentServices), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp)))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::Foo.Bar.State.QResultFactory>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::Foo.Bar.State.QBuilder>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton>(services, sp => new global::StrawberryShake.OperationExecutor(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp), () => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp), () => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp), strategy)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::StrawberryShake.Json.JsonResultPatcher>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)); + return services; + } + + private sealed class ClientServiceProvider : System.IServiceProvider, System.IDisposable + { + private readonly System.IServiceProvider _provider; + public ClientServiceProvider(System.IServiceProvider provider) + { + _provider = provider; + } + + public object? GetService(System.Type serviceType) + { + return _provider.GetService(serviceType); + } + + public void Dispose() + { + if (_provider is System.IDisposable d) + { + d.Dispose(); + } + } + } + } +} + + diff --git a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/DuplicateFragmentSpreadGeneratorTests.Generate_Should_Compile_When_Same_Object_Fragment_Spread_Twice.snap b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/DuplicateFragmentSpreadGeneratorTests.Generate_Should_Compile_When_Same_Object_Fragment_Spread_Twice.snap new file mode 100644 index 00000000000..6e01590bb21 --- /dev/null +++ b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/DuplicateFragmentSpreadGeneratorTests.Generate_Should_Compile_When_Same_Object_Fragment_Spread_Twice.snap @@ -0,0 +1,726 @@ +// ReSharper disable ArrangeObjectCreationWhenTypeEvident +// ReSharper disable BuiltInTypeReferenceStyle +// ReSharper disable ConvertToAutoProperty +// ReSharper disable InconsistentNaming +// ReSharper disable PartialTypeWithSinglePart +// ReSharper disable PreferConcreteValueOverDefault +// ReSharper disable RedundantNameQualifier +// ReSharper disable SuggestVarOrType_SimpleTypes +// ReSharper disable UnusedMember.Global +// ReSharper disable UnusedMethodReturnValue.Local +// ReSharper disable UnusedType.Global +// ReSharper disable UnusedVariable + +// FooClient + +// +#nullable enable annotations +#nullable disable warnings + +namespace Foo.Bar +{ + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultTypeGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QResult : global::System.IEquatable, IQResult + { + public QResult(global::Foo.Bar.IQ_Me? me) + { + Me = me; + } + + public global::Foo.Bar.IQ_Me? Me { get; } + + public virtual global::System.Boolean Equals(QResult? other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (other.GetType() != GetType()) + { + return false; + } + + return (((Me is null && other.Me is null) || Me != null && Me.Equals(other.Me))); + } + + public override global::System.Boolean Equals(global::System.Object? obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != GetType()) + { + return false; + } + + return Equals((QResult)obj); + } + + public override global::System.Int32 GetHashCode() + { + unchecked + { + int hash = 5; + if (Me != null) + { + hash ^= 397 * Me.GetHashCode(); + } + + return hash; + } + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultTypeGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class Q_Me_User : global::System.IEquatable, IQ_Me_User + { + public Q_Me_User(global::System.String id, global::System.String? name) + { + Id = id; + Name = name; + } + + public global::System.String Id { get; } + public global::System.String? Name { get; } + + public virtual global::System.Boolean Equals(Q_Me_User? other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (other.GetType() != GetType()) + { + return false; + } + + return (Id.Equals(other.Id)) && ((Name is null && other.Name is null) || Name != null && Name.Equals(other.Name)); + } + + public override global::System.Boolean Equals(global::System.Object? obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != GetType()) + { + return false; + } + + return Equals((Q_Me_User)obj); + } + + public override global::System.Int32 GetHashCode() + { + unchecked + { + int hash = 5; + hash ^= 397 * Id.GetHashCode(); + if (Name != null) + { + hash ^= 397 * Name.GetHashCode(); + } + + return hash; + } + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IQResult + { + public global::Foo.Bar.IQ_Me? Me { get; } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IUF + { + public global::System.String Id { get; } + public global::System.String? Name { get; } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IQ_Me : IUF + { + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IQ_Me_User : IQ_Me + { + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.OperationDocumentGenerator + /// + /// Represents the operation service of the Q GraphQL operation + /// + /// query Q { + /// me { + /// __typename + /// ...UF + /// ...UF + /// ... on User { + /// id + /// } + /// } + /// } + /// + /// fragment UF on User { + /// id + /// name + /// } + /// + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QQueryDocument : global::StrawberryShake.IDocument + { + private QQueryDocument() + { + } + + public static QQueryDocument Instance { get; } = new QQueryDocument(); + public global::StrawberryShake.OperationKind Kind => global::StrawberryShake.OperationKind.Query; + public global::System.ReadOnlySpan Body => "query Q { me { __typename ...UF ...UF ... on User { id } } } fragment UF on User { id name }"u8; + public global::StrawberryShake.DocumentHash Hash { get; } = new global::StrawberryShake.DocumentHash("sha1Hash", "71be448f229f1312d28d3b91e79710a8df60ea5a"); + + public override global::System.String ToString() + { +#if NETCOREAPP3_1_OR_GREATER + return global::System.Text.Encoding.UTF8.GetString(Body); +#else + return global::System.Text.Encoding.UTF8.GetString(Body.ToArray()); +#endif + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.OperationServiceGenerator + /// + /// Represents the operation service of the Q GraphQL operation + /// + /// query Q { + /// me { + /// __typename + /// ...UF + /// ...UF + /// ... on User { + /// id + /// } + /// } + /// } + /// + /// fragment UF on User { + /// id + /// name + /// } + /// + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QQuery : global::Foo.Bar.IQQuery + { + private readonly global::StrawberryShake.IOperationExecutor _operationExecutor; + private readonly global::System.Collections.Immutable.ImmutableArray> _configure = global::System.Collections.Immutable.ImmutableArray>.Empty; + public QQuery(global::StrawberryShake.IOperationExecutor operationExecutor) + { + _operationExecutor = operationExecutor ?? throw new global::System.ArgumentNullException(nameof(operationExecutor)); + } + + private QQuery(global::StrawberryShake.IOperationExecutor operationExecutor, global::System.Collections.Immutable.ImmutableArray> configure) + { + _operationExecutor = operationExecutor; + _configure = configure; + } + + global::System.Type global::StrawberryShake.IOperationRequestFactory.ResultType => typeof(IQResult); + + public global::Foo.Bar.IQQuery With(global::System.Action configure) + { + return new global::Foo.Bar.QQuery(_operationExecutor, _configure.Add(configure)); + } + + public global::Foo.Bar.IQQuery WithRequestUri(global::System.Uri requestUri) + { + return With(r => r.ContextData["StrawberryShake.Transport.Http.HttpConnection.RequestUri"] = requestUri); + } + + public global::Foo.Bar.IQQuery WithHttpClient(global::System.Net.Http.HttpClient httpClient) + { + return With(r => r.ContextData["StrawberryShake.Transport.Http.HttpConnection.HttpClient"] = httpClient); + } + + public async global::System.Threading.Tasks.Task> ExecuteAsync(global::System.Threading.CancellationToken cancellationToken = default) + { + var request = CreateRequest(); + foreach (var configure in _configure) + { + configure(request); + } + + return await _operationExecutor.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + } + + public global::System.IObservable> Watch(global::StrawberryShake.ExecutionStrategy? strategy = null) + { + var request = CreateRequest(); + return _operationExecutor.Watch(request, strategy); + } + + private global::StrawberryShake.OperationRequest CreateRequest() + { + return CreateRequest(null); + } + + private global::StrawberryShake.OperationRequest CreateRequest(global::System.Collections.Generic.IReadOnlyDictionary? variables) + { + return new global::StrawberryShake.OperationRequest(id: QQueryDocument.Instance.Hash.Value, name: "Q", document: QQueryDocument.Instance, strategy: global::StrawberryShake.RequestStrategy.Default); + } + + global::StrawberryShake.OperationRequest global::StrawberryShake.IOperationRequestFactory.Create(global::System.Collections.Generic.IReadOnlyDictionary? variables) + { + return CreateRequest(); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.OperationServiceInterfaceGenerator + /// + /// Represents the operation service of the Q GraphQL operation + /// + /// query Q { + /// me { + /// __typename + /// ...UF + /// ...UF + /// ... on User { + /// id + /// } + /// } + /// } + /// + /// fragment UF on User { + /// id + /// name + /// } + /// + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IQQuery : global::StrawberryShake.IOperationRequestFactory + { + global::Foo.Bar.IQQuery With(global::System.Action configure); + global::Foo.Bar.IQQuery WithRequestUri(global::System.Uri requestUri); + global::Foo.Bar.IQQuery WithHttpClient(global::System.Net.Http.HttpClient httpClient); + global::System.Threading.Tasks.Task> ExecuteAsync(global::System.Threading.CancellationToken cancellationToken = default); + global::System.IObservable> Watch(global::StrawberryShake.ExecutionStrategy? strategy = null); + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ClientGenerator + /// + /// Represents the FooClient GraphQL client + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class FooClient : global::Foo.Bar.IFooClient + { + private readonly global::Foo.Bar.IQQuery _q; + public FooClient(global::Foo.Bar.IQQuery q) + { + _q = q ?? throw new global::System.ArgumentNullException(nameof(q)); + } + + public static global::System.String ClientName => "FooClient"; + public global::Foo.Bar.IQQuery Q => _q; + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ClientInterfaceGenerator + /// + /// Represents the FooClient GraphQL client + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IFooClient + { + global::Foo.Bar.IQQuery Q { get; } + } +} + +namespace Foo.Bar.State +{ + // StrawberryShake.CodeGeneration.CSharp.Generators.EntityTypeGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "0.0.0.0")] + public partial class UserEntity + { + public UserEntity(global::System.String id = default !, global::System.String? name = default !) + { + Id = id; + Name = name; + } + + public global::System.String Id { get; } + public global::System.String? Name { get; } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultDataFactoryGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QResultFactory : global::StrawberryShake.IOperationResultDataFactory + { + private readonly global::StrawberryShake.IEntityStore _entityStore; + private readonly global::StrawberryShake.IEntityMapper _q_Me_UserFromUserEntityMapper; + public QResultFactory(global::StrawberryShake.IEntityStore entityStore, global::StrawberryShake.IEntityMapper q_Me_UserFromUserEntityMapper) + { + _entityStore = entityStore ?? throw new global::System.ArgumentNullException(nameof(entityStore)); + _q_Me_UserFromUserEntityMapper = q_Me_UserFromUserEntityMapper ?? throw new global::System.ArgumentNullException(nameof(q_Me_UserFromUserEntityMapper)); + } + + global::System.Type global::StrawberryShake.IOperationResultDataFactory.ResultType => typeof(global::Foo.Bar.IQResult); + + public QResult Create(global::StrawberryShake.IOperationResultDataInfo dataInfo, global::StrawberryShake.IEntityStoreSnapshot? snapshot = null) + { + if (snapshot is null) + { + snapshot = _entityStore.CurrentSnapshot; + } + + if (dataInfo is QResultInfo info) + { + return new QResult(MapIQ_Me(info.Me, snapshot)); + } + + throw new global::System.ArgumentException("QResultInfo expected."); + } + + private global::Foo.Bar.IQ_Me? MapIQ_Me(global::StrawberryShake.EntityId? entityId, global::StrawberryShake.IEntityStoreSnapshot snapshot) + { + if (entityId is null) + { + return null; + } + + if (entityId.Value.Name.Equals("User", global::System.StringComparison.Ordinal)) + { + return _q_Me_UserFromUserEntityMapper.Map(snapshot.GetEntity(entityId.Value) ?? throw new global::StrawberryShake.GraphQLClientException()); + } + + throw new global::System.NotSupportedException(); + } + + global::System.Object global::StrawberryShake.IOperationResultDataFactory.Create(global::StrawberryShake.IOperationResultDataInfo dataInfo, global::StrawberryShake.IEntityStoreSnapshot? snapshot) + { + return Create(dataInfo, snapshot); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInfoGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QResultInfo : global::StrawberryShake.IOperationResultDataInfo + { + private readonly global::System.Collections.Generic.IReadOnlyCollection _entityIds; + private readonly global::System.UInt64 _version; + public QResultInfo(global::StrawberryShake.EntityId? me, global::System.Collections.Generic.IReadOnlyCollection entityIds, global::System.UInt64 version) + { + Me = me; + _entityIds = entityIds ?? throw new global::System.ArgumentNullException(nameof(entityIds)); + _version = version; + } + + public global::StrawberryShake.EntityId? Me { get; } + public global::System.Collections.Generic.IReadOnlyCollection EntityIds => _entityIds; + public global::System.UInt64 Version => _version; + + public global::StrawberryShake.IOperationResultDataInfo WithVersion(global::System.UInt64 version) + { + return new QResultInfo(Me, _entityIds, version); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.JsonResultBuilderGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QBuilder : global::StrawberryShake.OperationResultBuilder + { + private readonly global::StrawberryShake.IEntityStore _entityStore; + private readonly global::StrawberryShake.IEntityIdSerializer _idSerializer; + private readonly global::StrawberryShake.Serialization.ILeafValueParser _iDParser; + private readonly global::StrawberryShake.Serialization.ILeafValueParser _stringParser; + public QBuilder(global::StrawberryShake.IEntityStore entityStore, global::StrawberryShake.IEntityIdSerializer idSerializer, global::StrawberryShake.IOperationResultDataFactory resultDataFactory, global::StrawberryShake.Serialization.ISerializerResolver serializerResolver) + { + _entityStore = entityStore ?? throw new global::System.ArgumentNullException(nameof(entityStore)); + _idSerializer = idSerializer ?? throw new global::System.ArgumentNullException(nameof(idSerializer)); + ResultDataFactory = resultDataFactory ?? throw new global::System.ArgumentNullException(nameof(resultDataFactory)); + _iDParser = serializerResolver.GetLeafValueParser("ID") ?? throw new global::System.ArgumentException("No serializer for type `ID` found."); + _stringParser = serializerResolver.GetLeafValueParser("String") ?? throw new global::System.ArgumentException("No serializer for type `String` found."); + } + + protected override global::StrawberryShake.IOperationResultDataFactory ResultDataFactory { get; } + + protected override global::StrawberryShake.IOperationResultDataInfo BuildData(global::System.Text.Json.JsonElement obj) + { + var entityIds = new global::System.Collections.Generic.HashSet(); + global::StrawberryShake.IEntityStoreSnapshot snapshot = default !; + global::StrawberryShake.EntityId? meId = default !; + _entityStore.Update(session => + { + meId = Update_IQ_MeEntity(session, global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "me"), entityIds); + snapshot = session.CurrentSnapshot; + }); + return new QResultInfo(meId, entityIds, snapshot.Version); + } + + private global::StrawberryShake.EntityId? Update_IQ_MeEntity(global::StrawberryShake.IEntityStoreUpdateSession session, global::System.Text.Json.JsonElement? obj, global::System.Collections.Generic.ISet entityIds) + { + if (!obj.HasValue) + { + return null; + } + + if (obj.Value.ValueKind == global::System.Text.Json.JsonValueKind.Null) + { + return null; + } + + global::StrawberryShake.EntityId entityId = _idSerializer.Parse(obj.Value); + entityIds.Add(entityId); + if (entityId.Name.Equals("User", global::System.StringComparison.Ordinal)) + { + if (session.CurrentSnapshot.TryGetEntity(entityId, out global::Foo.Bar.State.UserEntity? entity)) + { + session.SetEntity(entityId, new global::Foo.Bar.State.UserEntity(Deserialize_NonNullableString(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "id")), Deserialize_String(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "name")))); + } + else + { + session.SetEntity(entityId, new global::Foo.Bar.State.UserEntity(Deserialize_NonNullableString(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "id")), Deserialize_String(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "name")))); + } + + return entityId; + } + + throw new global::System.NotSupportedException(); + } + + private global::System.String Deserialize_NonNullableString(global::System.Text.Json.JsonElement? obj) + { + if (!obj.HasValue) + { + throw new global::System.ArgumentNullException(); + } + + if (obj.Value.ValueKind == global::System.Text.Json.JsonValueKind.Null) + { + throw new global::System.ArgumentNullException(); + } + + return _iDParser.Parse(obj.Value.GetString()!); + } + + private global::System.String? Deserialize_String(global::System.Text.Json.JsonElement? obj) + { + if (!obj.HasValue) + { + return null; + } + + if (obj.Value.ValueKind == global::System.Text.Json.JsonValueKind.Null) + { + return null; + } + + return _stringParser.Parse(obj.Value.GetString()!); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultFromEntityTypeMapperGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class Q_Me_UserFromUserEntityMapper : global::StrawberryShake.IEntityMapper + { + private readonly global::StrawberryShake.IEntityStore _entityStore; + public Q_Me_UserFromUserEntityMapper(global::StrawberryShake.IEntityStore entityStore) + { + _entityStore = entityStore ?? throw new global::System.ArgumentNullException(nameof(entityStore)); + } + + public Q_Me_User Map(global::Foo.Bar.State.UserEntity entity, global::StrawberryShake.IEntityStoreSnapshot? snapshot = null) + { + if (snapshot is null) + { + snapshot = _entityStore.CurrentSnapshot; + } + + return new Q_Me_User(entity.Id, entity.Name); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.EntityIdFactoryGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class FooClientEntityIdFactory : global::StrawberryShake.IEntityIdSerializer + { + private static readonly global::System.Text.Json.JsonWriterOptions _options = new global::System.Text.Json.JsonWriterOptions() + { + Indented = false + }; + public global::StrawberryShake.EntityId Parse(global::System.Text.Json.JsonElement obj) + { + global::System.String __typename = obj.GetProperty("__typename").GetString()!; + return __typename switch + { + "User" => ParseUserEntityId(obj, __typename), + _ => throw new global::System.NotSupportedException()}; + } + + public global::System.String Format(global::StrawberryShake.EntityId entityId) + { + return entityId.Name switch + { + "User" => FormatUserEntityId(entityId), + _ => throw new global::System.NotSupportedException()}; + } + + private global::StrawberryShake.EntityId ParseUserEntityId(global::System.Text.Json.JsonElement obj, global::System.String type) + { + return new global::StrawberryShake.EntityId(type, obj.GetProperty("id").GetString()!); + } + + private global::System.String FormatUserEntityId(global::StrawberryShake.EntityId entityId) + { + using var writer = new global::StrawberryShake.Internal.ArrayWriter(); + using var jsonWriter = new global::System.Text.Json.Utf8JsonWriter(writer, _options); + jsonWriter.WriteStartObject(); + jsonWriter.WriteString("__typename", entityId.Name); + jsonWriter.WriteString("id", (global::System.String)entityId.Value); + jsonWriter.WriteEndObject(); + jsonWriter.Flush(); + return global::System.Text.Encoding.UTF8.GetString(writer.GetInternalBuffer(), 0, writer.Length); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.StoreAccessorGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class FooClientStoreAccessor : global::StrawberryShake.StoreAccessor + { + public FooClientStoreAccessor(global::StrawberryShake.IOperationStore operationStore, global::StrawberryShake.IEntityStore entityStore, global::StrawberryShake.IEntityIdSerializer entityIdSerializer, global::System.Collections.Generic.IEnumerable requestFactories, global::System.Collections.Generic.IEnumerable resultDataFactories) : base(operationStore, entityStore, entityIdSerializer, requestFactories, resultDataFactories) + { + } + } +} + +namespace Microsoft.Extensions.DependencyInjection +{ + // StrawberryShake.CodeGeneration.CSharp.Generators.DependencyInjectionGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public static partial class FooClientServiceCollectionExtensions + { + public static global::StrawberryShake.IClientBuilder AddFooClient(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::StrawberryShake.ExecutionStrategy strategy = global::StrawberryShake.ExecutionStrategy.NetworkOnly) + { + var serviceCollection = new global::Microsoft.Extensions.DependencyInjection.ServiceCollection(); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => + { + ConfigureClientDefault(sp, serviceCollection, strategy); + return new ClientServiceProvider(global::Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(serviceCollection)); + }); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => new global::Foo.Bar.State.FooClientStoreAccessor(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + return new global::StrawberryShake.ClientBuilder("FooClient", services, serviceCollection); + } + + private static global::Microsoft.Extensions.DependencyInjection.IServiceCollection ConfigureClientDefault(global::System.IServiceProvider parentServices, global::Microsoft.Extensions.DependencyInjection.ServiceCollection services, global::StrawberryShake.ExecutionStrategy strategy = global::StrawberryShake.ExecutionStrategy.NetworkOnly) + { + global::Microsoft.Extensions.DependencyInjection.Extensions.ServiceCollectionDescriptorExtensions.TryAddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.Extensions.ServiceCollectionDescriptorExtensions.TryAddSingleton(services, sp => new global::StrawberryShake.OperationStore(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => + { + var clientFactory = global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(parentServices); + return new global::StrawberryShake.Transport.Http.HttpConnection(() => clientFactory.CreateClient("FooClient")); + }); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::Foo.Bar.State.Q_Me_UserFromUserEntityMapper>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => new global::StrawberryShake.Serialization.SerializerResolver(global::System.Linq.Enumerable.Concat(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(parentServices), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp)))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::Foo.Bar.State.QResultFactory>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::Foo.Bar.State.QBuilder>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton>(services, sp => new global::StrawberryShake.OperationExecutor(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp), () => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp), () => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp), strategy)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::StrawberryShake.Json.JsonResultPatcher>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)); + return services; + } + + private sealed class ClientServiceProvider : System.IServiceProvider, System.IDisposable + { + private readonly System.IServiceProvider _provider; + public ClientServiceProvider(System.IServiceProvider provider) + { + _provider = provider; + } + + public object? GetService(System.Type serviceType) + { + return _provider.GetService(serviceType); + } + + public void Dispose() + { + if (_provider is System.IDisposable d) + { + d.Dispose(); + } + } + } + } +} + + diff --git a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/DuplicateFragmentSpreadGeneratorTests.Generate_Should_Compile_When_Single_Fragment_Spread.snap b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/DuplicateFragmentSpreadGeneratorTests.Generate_Should_Compile_When_Single_Fragment_Spread.snap new file mode 100644 index 00000000000..b6783a78b1e --- /dev/null +++ b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/DuplicateFragmentSpreadGeneratorTests.Generate_Should_Compile_When_Single_Fragment_Spread.snap @@ -0,0 +1,723 @@ +// ReSharper disable ArrangeObjectCreationWhenTypeEvident +// ReSharper disable BuiltInTypeReferenceStyle +// ReSharper disable ConvertToAutoProperty +// ReSharper disable InconsistentNaming +// ReSharper disable PartialTypeWithSinglePart +// ReSharper disable PreferConcreteValueOverDefault +// ReSharper disable RedundantNameQualifier +// ReSharper disable SuggestVarOrType_SimpleTypes +// ReSharper disable UnusedMember.Global +// ReSharper disable UnusedMethodReturnValue.Local +// ReSharper disable UnusedType.Global +// ReSharper disable UnusedVariable + +// FooClient + +// +#nullable enable annotations +#nullable disable warnings + +namespace Foo.Bar +{ + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultTypeGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QResult : global::System.IEquatable, IQResult + { + public QResult(global::Foo.Bar.IQ_Me? me) + { + Me = me; + } + + public global::Foo.Bar.IQ_Me? Me { get; } + + public virtual global::System.Boolean Equals(QResult? other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (other.GetType() != GetType()) + { + return false; + } + + return (((Me is null && other.Me is null) || Me != null && Me.Equals(other.Me))); + } + + public override global::System.Boolean Equals(global::System.Object? obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != GetType()) + { + return false; + } + + return Equals((QResult)obj); + } + + public override global::System.Int32 GetHashCode() + { + unchecked + { + int hash = 5; + if (Me != null) + { + hash ^= 397 * Me.GetHashCode(); + } + + return hash; + } + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultTypeGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class Q_Me_User : global::System.IEquatable, IQ_Me_User + { + public Q_Me_User(global::System.String id, global::System.String? name) + { + Id = id; + Name = name; + } + + public global::System.String Id { get; } + public global::System.String? Name { get; } + + public virtual global::System.Boolean Equals(Q_Me_User? other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (other.GetType() != GetType()) + { + return false; + } + + return (Id.Equals(other.Id)) && ((Name is null && other.Name is null) || Name != null && Name.Equals(other.Name)); + } + + public override global::System.Boolean Equals(global::System.Object? obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != GetType()) + { + return false; + } + + return Equals((Q_Me_User)obj); + } + + public override global::System.Int32 GetHashCode() + { + unchecked + { + int hash = 5; + hash ^= 397 * Id.GetHashCode(); + if (Name != null) + { + hash ^= 397 * Name.GetHashCode(); + } + + return hash; + } + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IQResult + { + public global::Foo.Bar.IQ_Me? Me { get; } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IUF + { + public global::System.String Id { get; } + public global::System.String? Name { get; } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IQ_Me : IUF + { + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IQ_Me_User : IQ_Me + { + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.OperationDocumentGenerator + /// + /// Represents the operation service of the Q GraphQL operation + /// + /// query Q { + /// me { + /// __typename + /// ...UF + /// ... on User { + /// id + /// } + /// } + /// } + /// + /// fragment UF on User { + /// id + /// name + /// } + /// + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QQueryDocument : global::StrawberryShake.IDocument + { + private QQueryDocument() + { + } + + public static QQueryDocument Instance { get; } = new QQueryDocument(); + public global::StrawberryShake.OperationKind Kind => global::StrawberryShake.OperationKind.Query; + public global::System.ReadOnlySpan Body => "query Q { me { __typename ...UF ... on User { id } } } fragment UF on User { id name }"u8; + public global::StrawberryShake.DocumentHash Hash { get; } = new global::StrawberryShake.DocumentHash("sha1Hash", "f7ed571f5ace501da96de73ac2f435910d704def"); + + public override global::System.String ToString() + { +#if NETCOREAPP3_1_OR_GREATER + return global::System.Text.Encoding.UTF8.GetString(Body); +#else + return global::System.Text.Encoding.UTF8.GetString(Body.ToArray()); +#endif + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.OperationServiceGenerator + /// + /// Represents the operation service of the Q GraphQL operation + /// + /// query Q { + /// me { + /// __typename + /// ...UF + /// ... on User { + /// id + /// } + /// } + /// } + /// + /// fragment UF on User { + /// id + /// name + /// } + /// + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QQuery : global::Foo.Bar.IQQuery + { + private readonly global::StrawberryShake.IOperationExecutor _operationExecutor; + private readonly global::System.Collections.Immutable.ImmutableArray> _configure = global::System.Collections.Immutable.ImmutableArray>.Empty; + public QQuery(global::StrawberryShake.IOperationExecutor operationExecutor) + { + _operationExecutor = operationExecutor ?? throw new global::System.ArgumentNullException(nameof(operationExecutor)); + } + + private QQuery(global::StrawberryShake.IOperationExecutor operationExecutor, global::System.Collections.Immutable.ImmutableArray> configure) + { + _operationExecutor = operationExecutor; + _configure = configure; + } + + global::System.Type global::StrawberryShake.IOperationRequestFactory.ResultType => typeof(IQResult); + + public global::Foo.Bar.IQQuery With(global::System.Action configure) + { + return new global::Foo.Bar.QQuery(_operationExecutor, _configure.Add(configure)); + } + + public global::Foo.Bar.IQQuery WithRequestUri(global::System.Uri requestUri) + { + return With(r => r.ContextData["StrawberryShake.Transport.Http.HttpConnection.RequestUri"] = requestUri); + } + + public global::Foo.Bar.IQQuery WithHttpClient(global::System.Net.Http.HttpClient httpClient) + { + return With(r => r.ContextData["StrawberryShake.Transport.Http.HttpConnection.HttpClient"] = httpClient); + } + + public async global::System.Threading.Tasks.Task> ExecuteAsync(global::System.Threading.CancellationToken cancellationToken = default) + { + var request = CreateRequest(); + foreach (var configure in _configure) + { + configure(request); + } + + return await _operationExecutor.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + } + + public global::System.IObservable> Watch(global::StrawberryShake.ExecutionStrategy? strategy = null) + { + var request = CreateRequest(); + return _operationExecutor.Watch(request, strategy); + } + + private global::StrawberryShake.OperationRequest CreateRequest() + { + return CreateRequest(null); + } + + private global::StrawberryShake.OperationRequest CreateRequest(global::System.Collections.Generic.IReadOnlyDictionary? variables) + { + return new global::StrawberryShake.OperationRequest(id: QQueryDocument.Instance.Hash.Value, name: "Q", document: QQueryDocument.Instance, strategy: global::StrawberryShake.RequestStrategy.Default); + } + + global::StrawberryShake.OperationRequest global::StrawberryShake.IOperationRequestFactory.Create(global::System.Collections.Generic.IReadOnlyDictionary? variables) + { + return CreateRequest(); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.OperationServiceInterfaceGenerator + /// + /// Represents the operation service of the Q GraphQL operation + /// + /// query Q { + /// me { + /// __typename + /// ...UF + /// ... on User { + /// id + /// } + /// } + /// } + /// + /// fragment UF on User { + /// id + /// name + /// } + /// + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IQQuery : global::StrawberryShake.IOperationRequestFactory + { + global::Foo.Bar.IQQuery With(global::System.Action configure); + global::Foo.Bar.IQQuery WithRequestUri(global::System.Uri requestUri); + global::Foo.Bar.IQQuery WithHttpClient(global::System.Net.Http.HttpClient httpClient); + global::System.Threading.Tasks.Task> ExecuteAsync(global::System.Threading.CancellationToken cancellationToken = default); + global::System.IObservable> Watch(global::StrawberryShake.ExecutionStrategy? strategy = null); + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ClientGenerator + /// + /// Represents the FooClient GraphQL client + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class FooClient : global::Foo.Bar.IFooClient + { + private readonly global::Foo.Bar.IQQuery _q; + public FooClient(global::Foo.Bar.IQQuery q) + { + _q = q ?? throw new global::System.ArgumentNullException(nameof(q)); + } + + public static global::System.String ClientName => "FooClient"; + public global::Foo.Bar.IQQuery Q => _q; + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ClientInterfaceGenerator + /// + /// Represents the FooClient GraphQL client + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IFooClient + { + global::Foo.Bar.IQQuery Q { get; } + } +} + +namespace Foo.Bar.State +{ + // StrawberryShake.CodeGeneration.CSharp.Generators.EntityTypeGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "0.0.0.0")] + public partial class UserEntity + { + public UserEntity(global::System.String id = default !, global::System.String? name = default !) + { + Id = id; + Name = name; + } + + public global::System.String Id { get; } + public global::System.String? Name { get; } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultDataFactoryGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QResultFactory : global::StrawberryShake.IOperationResultDataFactory + { + private readonly global::StrawberryShake.IEntityStore _entityStore; + private readonly global::StrawberryShake.IEntityMapper _q_Me_UserFromUserEntityMapper; + public QResultFactory(global::StrawberryShake.IEntityStore entityStore, global::StrawberryShake.IEntityMapper q_Me_UserFromUserEntityMapper) + { + _entityStore = entityStore ?? throw new global::System.ArgumentNullException(nameof(entityStore)); + _q_Me_UserFromUserEntityMapper = q_Me_UserFromUserEntityMapper ?? throw new global::System.ArgumentNullException(nameof(q_Me_UserFromUserEntityMapper)); + } + + global::System.Type global::StrawberryShake.IOperationResultDataFactory.ResultType => typeof(global::Foo.Bar.IQResult); + + public QResult Create(global::StrawberryShake.IOperationResultDataInfo dataInfo, global::StrawberryShake.IEntityStoreSnapshot? snapshot = null) + { + if (snapshot is null) + { + snapshot = _entityStore.CurrentSnapshot; + } + + if (dataInfo is QResultInfo info) + { + return new QResult(MapIQ_Me(info.Me, snapshot)); + } + + throw new global::System.ArgumentException("QResultInfo expected."); + } + + private global::Foo.Bar.IQ_Me? MapIQ_Me(global::StrawberryShake.EntityId? entityId, global::StrawberryShake.IEntityStoreSnapshot snapshot) + { + if (entityId is null) + { + return null; + } + + if (entityId.Value.Name.Equals("User", global::System.StringComparison.Ordinal)) + { + return _q_Me_UserFromUserEntityMapper.Map(snapshot.GetEntity(entityId.Value) ?? throw new global::StrawberryShake.GraphQLClientException()); + } + + throw new global::System.NotSupportedException(); + } + + global::System.Object global::StrawberryShake.IOperationResultDataFactory.Create(global::StrawberryShake.IOperationResultDataInfo dataInfo, global::StrawberryShake.IEntityStoreSnapshot? snapshot) + { + return Create(dataInfo, snapshot); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInfoGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QResultInfo : global::StrawberryShake.IOperationResultDataInfo + { + private readonly global::System.Collections.Generic.IReadOnlyCollection _entityIds; + private readonly global::System.UInt64 _version; + public QResultInfo(global::StrawberryShake.EntityId? me, global::System.Collections.Generic.IReadOnlyCollection entityIds, global::System.UInt64 version) + { + Me = me; + _entityIds = entityIds ?? throw new global::System.ArgumentNullException(nameof(entityIds)); + _version = version; + } + + public global::StrawberryShake.EntityId? Me { get; } + public global::System.Collections.Generic.IReadOnlyCollection EntityIds => _entityIds; + public global::System.UInt64 Version => _version; + + public global::StrawberryShake.IOperationResultDataInfo WithVersion(global::System.UInt64 version) + { + return new QResultInfo(Me, _entityIds, version); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.JsonResultBuilderGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QBuilder : global::StrawberryShake.OperationResultBuilder + { + private readonly global::StrawberryShake.IEntityStore _entityStore; + private readonly global::StrawberryShake.IEntityIdSerializer _idSerializer; + private readonly global::StrawberryShake.Serialization.ILeafValueParser _iDParser; + private readonly global::StrawberryShake.Serialization.ILeafValueParser _stringParser; + public QBuilder(global::StrawberryShake.IEntityStore entityStore, global::StrawberryShake.IEntityIdSerializer idSerializer, global::StrawberryShake.IOperationResultDataFactory resultDataFactory, global::StrawberryShake.Serialization.ISerializerResolver serializerResolver) + { + _entityStore = entityStore ?? throw new global::System.ArgumentNullException(nameof(entityStore)); + _idSerializer = idSerializer ?? throw new global::System.ArgumentNullException(nameof(idSerializer)); + ResultDataFactory = resultDataFactory ?? throw new global::System.ArgumentNullException(nameof(resultDataFactory)); + _iDParser = serializerResolver.GetLeafValueParser("ID") ?? throw new global::System.ArgumentException("No serializer for type `ID` found."); + _stringParser = serializerResolver.GetLeafValueParser("String") ?? throw new global::System.ArgumentException("No serializer for type `String` found."); + } + + protected override global::StrawberryShake.IOperationResultDataFactory ResultDataFactory { get; } + + protected override global::StrawberryShake.IOperationResultDataInfo BuildData(global::System.Text.Json.JsonElement obj) + { + var entityIds = new global::System.Collections.Generic.HashSet(); + global::StrawberryShake.IEntityStoreSnapshot snapshot = default !; + global::StrawberryShake.EntityId? meId = default !; + _entityStore.Update(session => + { + meId = Update_IQ_MeEntity(session, global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "me"), entityIds); + snapshot = session.CurrentSnapshot; + }); + return new QResultInfo(meId, entityIds, snapshot.Version); + } + + private global::StrawberryShake.EntityId? Update_IQ_MeEntity(global::StrawberryShake.IEntityStoreUpdateSession session, global::System.Text.Json.JsonElement? obj, global::System.Collections.Generic.ISet entityIds) + { + if (!obj.HasValue) + { + return null; + } + + if (obj.Value.ValueKind == global::System.Text.Json.JsonValueKind.Null) + { + return null; + } + + global::StrawberryShake.EntityId entityId = _idSerializer.Parse(obj.Value); + entityIds.Add(entityId); + if (entityId.Name.Equals("User", global::System.StringComparison.Ordinal)) + { + if (session.CurrentSnapshot.TryGetEntity(entityId, out global::Foo.Bar.State.UserEntity? entity)) + { + session.SetEntity(entityId, new global::Foo.Bar.State.UserEntity(Deserialize_NonNullableString(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "id")), Deserialize_String(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "name")))); + } + else + { + session.SetEntity(entityId, new global::Foo.Bar.State.UserEntity(Deserialize_NonNullableString(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "id")), Deserialize_String(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "name")))); + } + + return entityId; + } + + throw new global::System.NotSupportedException(); + } + + private global::System.String Deserialize_NonNullableString(global::System.Text.Json.JsonElement? obj) + { + if (!obj.HasValue) + { + throw new global::System.ArgumentNullException(); + } + + if (obj.Value.ValueKind == global::System.Text.Json.JsonValueKind.Null) + { + throw new global::System.ArgumentNullException(); + } + + return _iDParser.Parse(obj.Value.GetString()!); + } + + private global::System.String? Deserialize_String(global::System.Text.Json.JsonElement? obj) + { + if (!obj.HasValue) + { + return null; + } + + if (obj.Value.ValueKind == global::System.Text.Json.JsonValueKind.Null) + { + return null; + } + + return _stringParser.Parse(obj.Value.GetString()!); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultFromEntityTypeMapperGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class Q_Me_UserFromUserEntityMapper : global::StrawberryShake.IEntityMapper + { + private readonly global::StrawberryShake.IEntityStore _entityStore; + public Q_Me_UserFromUserEntityMapper(global::StrawberryShake.IEntityStore entityStore) + { + _entityStore = entityStore ?? throw new global::System.ArgumentNullException(nameof(entityStore)); + } + + public Q_Me_User Map(global::Foo.Bar.State.UserEntity entity, global::StrawberryShake.IEntityStoreSnapshot? snapshot = null) + { + if (snapshot is null) + { + snapshot = _entityStore.CurrentSnapshot; + } + + return new Q_Me_User(entity.Id, entity.Name); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.EntityIdFactoryGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class FooClientEntityIdFactory : global::StrawberryShake.IEntityIdSerializer + { + private static readonly global::System.Text.Json.JsonWriterOptions _options = new global::System.Text.Json.JsonWriterOptions() + { + Indented = false + }; + public global::StrawberryShake.EntityId Parse(global::System.Text.Json.JsonElement obj) + { + global::System.String __typename = obj.GetProperty("__typename").GetString()!; + return __typename switch + { + "User" => ParseUserEntityId(obj, __typename), + _ => throw new global::System.NotSupportedException()}; + } + + public global::System.String Format(global::StrawberryShake.EntityId entityId) + { + return entityId.Name switch + { + "User" => FormatUserEntityId(entityId), + _ => throw new global::System.NotSupportedException()}; + } + + private global::StrawberryShake.EntityId ParseUserEntityId(global::System.Text.Json.JsonElement obj, global::System.String type) + { + return new global::StrawberryShake.EntityId(type, obj.GetProperty("id").GetString()!); + } + + private global::System.String FormatUserEntityId(global::StrawberryShake.EntityId entityId) + { + using var writer = new global::StrawberryShake.Internal.ArrayWriter(); + using var jsonWriter = new global::System.Text.Json.Utf8JsonWriter(writer, _options); + jsonWriter.WriteStartObject(); + jsonWriter.WriteString("__typename", entityId.Name); + jsonWriter.WriteString("id", (global::System.String)entityId.Value); + jsonWriter.WriteEndObject(); + jsonWriter.Flush(); + return global::System.Text.Encoding.UTF8.GetString(writer.GetInternalBuffer(), 0, writer.Length); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.StoreAccessorGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class FooClientStoreAccessor : global::StrawberryShake.StoreAccessor + { + public FooClientStoreAccessor(global::StrawberryShake.IOperationStore operationStore, global::StrawberryShake.IEntityStore entityStore, global::StrawberryShake.IEntityIdSerializer entityIdSerializer, global::System.Collections.Generic.IEnumerable requestFactories, global::System.Collections.Generic.IEnumerable resultDataFactories) : base(operationStore, entityStore, entityIdSerializer, requestFactories, resultDataFactories) + { + } + } +} + +namespace Microsoft.Extensions.DependencyInjection +{ + // StrawberryShake.CodeGeneration.CSharp.Generators.DependencyInjectionGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public static partial class FooClientServiceCollectionExtensions + { + public static global::StrawberryShake.IClientBuilder AddFooClient(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::StrawberryShake.ExecutionStrategy strategy = global::StrawberryShake.ExecutionStrategy.NetworkOnly) + { + var serviceCollection = new global::Microsoft.Extensions.DependencyInjection.ServiceCollection(); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => + { + ConfigureClientDefault(sp, serviceCollection, strategy); + return new ClientServiceProvider(global::Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(serviceCollection)); + }); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => new global::Foo.Bar.State.FooClientStoreAccessor(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + return new global::StrawberryShake.ClientBuilder("FooClient", services, serviceCollection); + } + + private static global::Microsoft.Extensions.DependencyInjection.IServiceCollection ConfigureClientDefault(global::System.IServiceProvider parentServices, global::Microsoft.Extensions.DependencyInjection.ServiceCollection services, global::StrawberryShake.ExecutionStrategy strategy = global::StrawberryShake.ExecutionStrategy.NetworkOnly) + { + global::Microsoft.Extensions.DependencyInjection.Extensions.ServiceCollectionDescriptorExtensions.TryAddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.Extensions.ServiceCollectionDescriptorExtensions.TryAddSingleton(services, sp => new global::StrawberryShake.OperationStore(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => + { + var clientFactory = global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(parentServices); + return new global::StrawberryShake.Transport.Http.HttpConnection(() => clientFactory.CreateClient("FooClient")); + }); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::Foo.Bar.State.Q_Me_UserFromUserEntityMapper>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => new global::StrawberryShake.Serialization.SerializerResolver(global::System.Linq.Enumerable.Concat(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(parentServices), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp)))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::Foo.Bar.State.QResultFactory>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::Foo.Bar.State.QBuilder>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton>(services, sp => new global::StrawberryShake.OperationExecutor(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp), () => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp), () => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp), strategy)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::StrawberryShake.Json.JsonResultPatcher>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)); + return services; + } + + private sealed class ClientServiceProvider : System.IServiceProvider, System.IDisposable + { + private readonly System.IServiceProvider _provider; + public ClientServiceProvider(System.IServiceProvider provider) + { + _provider = provider; + } + + public object? GetService(System.Type serviceType) + { + return _provider.GetService(serviceType); + } + + public void Dispose() + { + if (_provider is System.IDisposable d) + { + d.Dispose(); + } + } + } + } +} + + diff --git a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/DuplicateFragmentSpreadGeneratorTests.Generate_Should_Compile_When_Two_Different_Fragments_Spread.snap b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/DuplicateFragmentSpreadGeneratorTests.Generate_Should_Compile_When_Two_Different_Fragments_Spread.snap new file mode 100644 index 00000000000..4584fe2a4d6 --- /dev/null +++ b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/DuplicateFragmentSpreadGeneratorTests.Generate_Should_Compile_When_Two_Different_Fragments_Spread.snap @@ -0,0 +1,754 @@ +// ReSharper disable ArrangeObjectCreationWhenTypeEvident +// ReSharper disable BuiltInTypeReferenceStyle +// ReSharper disable ConvertToAutoProperty +// ReSharper disable InconsistentNaming +// ReSharper disable PartialTypeWithSinglePart +// ReSharper disable PreferConcreteValueOverDefault +// ReSharper disable RedundantNameQualifier +// ReSharper disable SuggestVarOrType_SimpleTypes +// ReSharper disable UnusedMember.Global +// ReSharper disable UnusedMethodReturnValue.Local +// ReSharper disable UnusedType.Global +// ReSharper disable UnusedVariable + +// FooClient + +// +#nullable enable annotations +#nullable disable warnings + +namespace Foo.Bar +{ + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultTypeGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QResult : global::System.IEquatable, IQResult + { + public QResult(global::Foo.Bar.IQ_Me? me) + { + Me = me; + } + + public global::Foo.Bar.IQ_Me? Me { get; } + + public virtual global::System.Boolean Equals(QResult? other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (other.GetType() != GetType()) + { + return false; + } + + return (((Me is null && other.Me is null) || Me != null && Me.Equals(other.Me))); + } + + public override global::System.Boolean Equals(global::System.Object? obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != GetType()) + { + return false; + } + + return Equals((QResult)obj); + } + + public override global::System.Int32 GetHashCode() + { + unchecked + { + int hash = 5; + if (Me != null) + { + hash ^= 397 * Me.GetHashCode(); + } + + return hash; + } + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultTypeGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class Q_Me_User : global::System.IEquatable, IQ_Me_User + { + public Q_Me_User(global::System.String id, global::System.String? name, global::System.String? email) + { + Id = id; + Name = name; + Email = email; + } + + public global::System.String Id { get; } + public global::System.String? Name { get; } + public global::System.String? Email { get; } + + public virtual global::System.Boolean Equals(Q_Me_User? other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (other.GetType() != GetType()) + { + return false; + } + + return (Id.Equals(other.Id)) && ((Name is null && other.Name is null) || Name != null && Name.Equals(other.Name)) && ((Email is null && other.Email is null) || Email != null && Email.Equals(other.Email)); + } + + public override global::System.Boolean Equals(global::System.Object? obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != GetType()) + { + return false; + } + + return Equals((Q_Me_User)obj); + } + + public override global::System.Int32 GetHashCode() + { + unchecked + { + int hash = 5; + hash ^= 397 * Id.GetHashCode(); + if (Name != null) + { + hash ^= 397 * Name.GetHashCode(); + } + + if (Email != null) + { + hash ^= 397 * Email.GetHashCode(); + } + + return hash; + } + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IQResult + { + public global::Foo.Bar.IQ_Me? Me { get; } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IUF + { + public global::System.String Id { get; } + public global::System.String? Name { get; } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IUG + { + public global::System.String? Email { get; } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IQ_Me : IUF, IUG + { + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IQ_Me_User : IQ_Me + { + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.OperationDocumentGenerator + /// + /// Represents the operation service of the Q GraphQL operation + /// + /// query Q { + /// me { + /// __typename + /// ...UF + /// ...UG + /// ... on User { + /// id + /// } + /// } + /// } + /// + /// fragment UF on User { + /// id + /// name + /// } + /// + /// fragment UG on User { + /// email + /// } + /// + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QQueryDocument : global::StrawberryShake.IDocument + { + private QQueryDocument() + { + } + + public static QQueryDocument Instance { get; } = new QQueryDocument(); + public global::StrawberryShake.OperationKind Kind => global::StrawberryShake.OperationKind.Query; + public global::System.ReadOnlySpan Body => "query Q { me { __typename ...UF ...UG ... on User { id } } } fragment UF on User { id name } fragment UG on User { email }"u8; + public global::StrawberryShake.DocumentHash Hash { get; } = new global::StrawberryShake.DocumentHash("sha1Hash", "0262c25f22fb0fa110c488bcc536a03cd2d4931a"); + + public override global::System.String ToString() + { +#if NETCOREAPP3_1_OR_GREATER + return global::System.Text.Encoding.UTF8.GetString(Body); +#else + return global::System.Text.Encoding.UTF8.GetString(Body.ToArray()); +#endif + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.OperationServiceGenerator + /// + /// Represents the operation service of the Q GraphQL operation + /// + /// query Q { + /// me { + /// __typename + /// ...UF + /// ...UG + /// ... on User { + /// id + /// } + /// } + /// } + /// + /// fragment UF on User { + /// id + /// name + /// } + /// + /// fragment UG on User { + /// email + /// } + /// + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QQuery : global::Foo.Bar.IQQuery + { + private readonly global::StrawberryShake.IOperationExecutor _operationExecutor; + private readonly global::System.Collections.Immutable.ImmutableArray> _configure = global::System.Collections.Immutable.ImmutableArray>.Empty; + public QQuery(global::StrawberryShake.IOperationExecutor operationExecutor) + { + _operationExecutor = operationExecutor ?? throw new global::System.ArgumentNullException(nameof(operationExecutor)); + } + + private QQuery(global::StrawberryShake.IOperationExecutor operationExecutor, global::System.Collections.Immutable.ImmutableArray> configure) + { + _operationExecutor = operationExecutor; + _configure = configure; + } + + global::System.Type global::StrawberryShake.IOperationRequestFactory.ResultType => typeof(IQResult); + + public global::Foo.Bar.IQQuery With(global::System.Action configure) + { + return new global::Foo.Bar.QQuery(_operationExecutor, _configure.Add(configure)); + } + + public global::Foo.Bar.IQQuery WithRequestUri(global::System.Uri requestUri) + { + return With(r => r.ContextData["StrawberryShake.Transport.Http.HttpConnection.RequestUri"] = requestUri); + } + + public global::Foo.Bar.IQQuery WithHttpClient(global::System.Net.Http.HttpClient httpClient) + { + return With(r => r.ContextData["StrawberryShake.Transport.Http.HttpConnection.HttpClient"] = httpClient); + } + + public async global::System.Threading.Tasks.Task> ExecuteAsync(global::System.Threading.CancellationToken cancellationToken = default) + { + var request = CreateRequest(); + foreach (var configure in _configure) + { + configure(request); + } + + return await _operationExecutor.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + } + + public global::System.IObservable> Watch(global::StrawberryShake.ExecutionStrategy? strategy = null) + { + var request = CreateRequest(); + return _operationExecutor.Watch(request, strategy); + } + + private global::StrawberryShake.OperationRequest CreateRequest() + { + return CreateRequest(null); + } + + private global::StrawberryShake.OperationRequest CreateRequest(global::System.Collections.Generic.IReadOnlyDictionary? variables) + { + return new global::StrawberryShake.OperationRequest(id: QQueryDocument.Instance.Hash.Value, name: "Q", document: QQueryDocument.Instance, strategy: global::StrawberryShake.RequestStrategy.Default); + } + + global::StrawberryShake.OperationRequest global::StrawberryShake.IOperationRequestFactory.Create(global::System.Collections.Generic.IReadOnlyDictionary? variables) + { + return CreateRequest(); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.OperationServiceInterfaceGenerator + /// + /// Represents the operation service of the Q GraphQL operation + /// + /// query Q { + /// me { + /// __typename + /// ...UF + /// ...UG + /// ... on User { + /// id + /// } + /// } + /// } + /// + /// fragment UF on User { + /// id + /// name + /// } + /// + /// fragment UG on User { + /// email + /// } + /// + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IQQuery : global::StrawberryShake.IOperationRequestFactory + { + global::Foo.Bar.IQQuery With(global::System.Action configure); + global::Foo.Bar.IQQuery WithRequestUri(global::System.Uri requestUri); + global::Foo.Bar.IQQuery WithHttpClient(global::System.Net.Http.HttpClient httpClient); + global::System.Threading.Tasks.Task> ExecuteAsync(global::System.Threading.CancellationToken cancellationToken = default); + global::System.IObservable> Watch(global::StrawberryShake.ExecutionStrategy? strategy = null); + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ClientGenerator + /// + /// Represents the FooClient GraphQL client + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class FooClient : global::Foo.Bar.IFooClient + { + private readonly global::Foo.Bar.IQQuery _q; + public FooClient(global::Foo.Bar.IQQuery q) + { + _q = q ?? throw new global::System.ArgumentNullException(nameof(q)); + } + + public static global::System.String ClientName => "FooClient"; + public global::Foo.Bar.IQQuery Q => _q; + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ClientInterfaceGenerator + /// + /// Represents the FooClient GraphQL client + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IFooClient + { + global::Foo.Bar.IQQuery Q { get; } + } +} + +namespace Foo.Bar.State +{ + // StrawberryShake.CodeGeneration.CSharp.Generators.EntityTypeGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "0.0.0.0")] + public partial class UserEntity + { + public UserEntity(global::System.String id = default !, global::System.String? name = default !, global::System.String? email = default !) + { + Id = id; + Name = name; + Email = email; + } + + public global::System.String Id { get; } + public global::System.String? Name { get; } + public global::System.String? Email { get; } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultDataFactoryGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QResultFactory : global::StrawberryShake.IOperationResultDataFactory + { + private readonly global::StrawberryShake.IEntityStore _entityStore; + private readonly global::StrawberryShake.IEntityMapper _q_Me_UserFromUserEntityMapper; + public QResultFactory(global::StrawberryShake.IEntityStore entityStore, global::StrawberryShake.IEntityMapper q_Me_UserFromUserEntityMapper) + { + _entityStore = entityStore ?? throw new global::System.ArgumentNullException(nameof(entityStore)); + _q_Me_UserFromUserEntityMapper = q_Me_UserFromUserEntityMapper ?? throw new global::System.ArgumentNullException(nameof(q_Me_UserFromUserEntityMapper)); + } + + global::System.Type global::StrawberryShake.IOperationResultDataFactory.ResultType => typeof(global::Foo.Bar.IQResult); + + public QResult Create(global::StrawberryShake.IOperationResultDataInfo dataInfo, global::StrawberryShake.IEntityStoreSnapshot? snapshot = null) + { + if (snapshot is null) + { + snapshot = _entityStore.CurrentSnapshot; + } + + if (dataInfo is QResultInfo info) + { + return new QResult(MapIQ_Me(info.Me, snapshot)); + } + + throw new global::System.ArgumentException("QResultInfo expected."); + } + + private global::Foo.Bar.IQ_Me? MapIQ_Me(global::StrawberryShake.EntityId? entityId, global::StrawberryShake.IEntityStoreSnapshot snapshot) + { + if (entityId is null) + { + return null; + } + + if (entityId.Value.Name.Equals("User", global::System.StringComparison.Ordinal)) + { + return _q_Me_UserFromUserEntityMapper.Map(snapshot.GetEntity(entityId.Value) ?? throw new global::StrawberryShake.GraphQLClientException()); + } + + throw new global::System.NotSupportedException(); + } + + global::System.Object global::StrawberryShake.IOperationResultDataFactory.Create(global::StrawberryShake.IOperationResultDataInfo dataInfo, global::StrawberryShake.IEntityStoreSnapshot? snapshot) + { + return Create(dataInfo, snapshot); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInfoGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QResultInfo : global::StrawberryShake.IOperationResultDataInfo + { + private readonly global::System.Collections.Generic.IReadOnlyCollection _entityIds; + private readonly global::System.UInt64 _version; + public QResultInfo(global::StrawberryShake.EntityId? me, global::System.Collections.Generic.IReadOnlyCollection entityIds, global::System.UInt64 version) + { + Me = me; + _entityIds = entityIds ?? throw new global::System.ArgumentNullException(nameof(entityIds)); + _version = version; + } + + public global::StrawberryShake.EntityId? Me { get; } + public global::System.Collections.Generic.IReadOnlyCollection EntityIds => _entityIds; + public global::System.UInt64 Version => _version; + + public global::StrawberryShake.IOperationResultDataInfo WithVersion(global::System.UInt64 version) + { + return new QResultInfo(Me, _entityIds, version); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.JsonResultBuilderGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class QBuilder : global::StrawberryShake.OperationResultBuilder + { + private readonly global::StrawberryShake.IEntityStore _entityStore; + private readonly global::StrawberryShake.IEntityIdSerializer _idSerializer; + private readonly global::StrawberryShake.Serialization.ILeafValueParser _iDParser; + private readonly global::StrawberryShake.Serialization.ILeafValueParser _stringParser; + public QBuilder(global::StrawberryShake.IEntityStore entityStore, global::StrawberryShake.IEntityIdSerializer idSerializer, global::StrawberryShake.IOperationResultDataFactory resultDataFactory, global::StrawberryShake.Serialization.ISerializerResolver serializerResolver) + { + _entityStore = entityStore ?? throw new global::System.ArgumentNullException(nameof(entityStore)); + _idSerializer = idSerializer ?? throw new global::System.ArgumentNullException(nameof(idSerializer)); + ResultDataFactory = resultDataFactory ?? throw new global::System.ArgumentNullException(nameof(resultDataFactory)); + _iDParser = serializerResolver.GetLeafValueParser("ID") ?? throw new global::System.ArgumentException("No serializer for type `ID` found."); + _stringParser = serializerResolver.GetLeafValueParser("String") ?? throw new global::System.ArgumentException("No serializer for type `String` found."); + } + + protected override global::StrawberryShake.IOperationResultDataFactory ResultDataFactory { get; } + + protected override global::StrawberryShake.IOperationResultDataInfo BuildData(global::System.Text.Json.JsonElement obj) + { + var entityIds = new global::System.Collections.Generic.HashSet(); + global::StrawberryShake.IEntityStoreSnapshot snapshot = default !; + global::StrawberryShake.EntityId? meId = default !; + _entityStore.Update(session => + { + meId = Update_IQ_MeEntity(session, global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "me"), entityIds); + snapshot = session.CurrentSnapshot; + }); + return new QResultInfo(meId, entityIds, snapshot.Version); + } + + private global::StrawberryShake.EntityId? Update_IQ_MeEntity(global::StrawberryShake.IEntityStoreUpdateSession session, global::System.Text.Json.JsonElement? obj, global::System.Collections.Generic.ISet entityIds) + { + if (!obj.HasValue) + { + return null; + } + + if (obj.Value.ValueKind == global::System.Text.Json.JsonValueKind.Null) + { + return null; + } + + global::StrawberryShake.EntityId entityId = _idSerializer.Parse(obj.Value); + entityIds.Add(entityId); + if (entityId.Name.Equals("User", global::System.StringComparison.Ordinal)) + { + if (session.CurrentSnapshot.TryGetEntity(entityId, out global::Foo.Bar.State.UserEntity? entity)) + { + session.SetEntity(entityId, new global::Foo.Bar.State.UserEntity(Deserialize_NonNullableString(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "id")), Deserialize_String(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "name")), Deserialize_String(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "email")))); + } + else + { + session.SetEntity(entityId, new global::Foo.Bar.State.UserEntity(Deserialize_NonNullableString(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "id")), Deserialize_String(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "name")), Deserialize_String(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "email")))); + } + + return entityId; + } + + throw new global::System.NotSupportedException(); + } + + private global::System.String Deserialize_NonNullableString(global::System.Text.Json.JsonElement? obj) + { + if (!obj.HasValue) + { + throw new global::System.ArgumentNullException(); + } + + if (obj.Value.ValueKind == global::System.Text.Json.JsonValueKind.Null) + { + throw new global::System.ArgumentNullException(); + } + + return _iDParser.Parse(obj.Value.GetString()!); + } + + private global::System.String? Deserialize_String(global::System.Text.Json.JsonElement? obj) + { + if (!obj.HasValue) + { + return null; + } + + if (obj.Value.ValueKind == global::System.Text.Json.JsonValueKind.Null) + { + return null; + } + + return _stringParser.Parse(obj.Value.GetString()!); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultFromEntityTypeMapperGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class Q_Me_UserFromUserEntityMapper : global::StrawberryShake.IEntityMapper + { + private readonly global::StrawberryShake.IEntityStore _entityStore; + public Q_Me_UserFromUserEntityMapper(global::StrawberryShake.IEntityStore entityStore) + { + _entityStore = entityStore ?? throw new global::System.ArgumentNullException(nameof(entityStore)); + } + + public Q_Me_User Map(global::Foo.Bar.State.UserEntity entity, global::StrawberryShake.IEntityStoreSnapshot? snapshot = null) + { + if (snapshot is null) + { + snapshot = _entityStore.CurrentSnapshot; + } + + return new Q_Me_User(entity.Id, entity.Name, entity.Email); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.EntityIdFactoryGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class FooClientEntityIdFactory : global::StrawberryShake.IEntityIdSerializer + { + private static readonly global::System.Text.Json.JsonWriterOptions _options = new global::System.Text.Json.JsonWriterOptions() + { + Indented = false + }; + public global::StrawberryShake.EntityId Parse(global::System.Text.Json.JsonElement obj) + { + global::System.String __typename = obj.GetProperty("__typename").GetString()!; + return __typename switch + { + "User" => ParseUserEntityId(obj, __typename), + _ => throw new global::System.NotSupportedException()}; + } + + public global::System.String Format(global::StrawberryShake.EntityId entityId) + { + return entityId.Name switch + { + "User" => FormatUserEntityId(entityId), + _ => throw new global::System.NotSupportedException()}; + } + + private global::StrawberryShake.EntityId ParseUserEntityId(global::System.Text.Json.JsonElement obj, global::System.String type) + { + return new global::StrawberryShake.EntityId(type, obj.GetProperty("id").GetString()!); + } + + private global::System.String FormatUserEntityId(global::StrawberryShake.EntityId entityId) + { + using var writer = new global::StrawberryShake.Internal.ArrayWriter(); + using var jsonWriter = new global::System.Text.Json.Utf8JsonWriter(writer, _options); + jsonWriter.WriteStartObject(); + jsonWriter.WriteString("__typename", entityId.Name); + jsonWriter.WriteString("id", (global::System.String)entityId.Value); + jsonWriter.WriteEndObject(); + jsonWriter.Flush(); + return global::System.Text.Encoding.UTF8.GetString(writer.GetInternalBuffer(), 0, writer.Length); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.StoreAccessorGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class FooClientStoreAccessor : global::StrawberryShake.StoreAccessor + { + public FooClientStoreAccessor(global::StrawberryShake.IOperationStore operationStore, global::StrawberryShake.IEntityStore entityStore, global::StrawberryShake.IEntityIdSerializer entityIdSerializer, global::System.Collections.Generic.IEnumerable requestFactories, global::System.Collections.Generic.IEnumerable resultDataFactories) : base(operationStore, entityStore, entityIdSerializer, requestFactories, resultDataFactories) + { + } + } +} + +namespace Microsoft.Extensions.DependencyInjection +{ + // StrawberryShake.CodeGeneration.CSharp.Generators.DependencyInjectionGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public static partial class FooClientServiceCollectionExtensions + { + public static global::StrawberryShake.IClientBuilder AddFooClient(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::StrawberryShake.ExecutionStrategy strategy = global::StrawberryShake.ExecutionStrategy.NetworkOnly) + { + var serviceCollection = new global::Microsoft.Extensions.DependencyInjection.ServiceCollection(); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => + { + ConfigureClientDefault(sp, serviceCollection, strategy); + return new ClientServiceProvider(global::Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(serviceCollection)); + }); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => new global::Foo.Bar.State.FooClientStoreAccessor(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + return new global::StrawberryShake.ClientBuilder("FooClient", services, serviceCollection); + } + + private static global::Microsoft.Extensions.DependencyInjection.IServiceCollection ConfigureClientDefault(global::System.IServiceProvider parentServices, global::Microsoft.Extensions.DependencyInjection.ServiceCollection services, global::StrawberryShake.ExecutionStrategy strategy = global::StrawberryShake.ExecutionStrategy.NetworkOnly) + { + global::Microsoft.Extensions.DependencyInjection.Extensions.ServiceCollectionDescriptorExtensions.TryAddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.Extensions.ServiceCollectionDescriptorExtensions.TryAddSingleton(services, sp => new global::StrawberryShake.OperationStore(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => + { + var clientFactory = global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(parentServices); + return new global::StrawberryShake.Transport.Http.HttpConnection(() => clientFactory.CreateClient("FooClient")); + }); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::Foo.Bar.State.Q_Me_UserFromUserEntityMapper>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => new global::StrawberryShake.Serialization.SerializerResolver(global::System.Linq.Enumerable.Concat(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(parentServices), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp)))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::Foo.Bar.State.QResultFactory>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::Foo.Bar.State.QBuilder>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton>(services, sp => new global::StrawberryShake.OperationExecutor(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp), () => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp), () => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp), strategy)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::StrawberryShake.Json.JsonResultPatcher>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)); + return services; + } + + private sealed class ClientServiceProvider : System.IServiceProvider, System.IDisposable + { + private readonly System.IServiceProvider _provider; + public ClientServiceProvider(System.IServiceProvider provider) + { + _provider = provider; + } + + public object? GetService(System.Type serviceType) + { + return _provider.GetService(serviceType); + } + + public void Dispose() + { + if (_provider is System.IDisposable d) + { + d.Dispose(); + } + } + } + } +} + +