From 39994140cad612e6c65f7ae41f563b6319904bcd Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 27 Jun 2026 15:54:09 +0200 Subject: [PATCH] fix(strawberry-shake): generate compilable upload mappers for multiple Upload fields StrawberryShake emitted invalid C# whenever a type or operation involved more than one Upload-typed field. Two defects in the file-mapper generator combined to break compilation: 1. The pattern variable in the `Upload` scalar mapper was hardcoded to `u`, so an input type with several Upload fields produced multiple `value is Upload u ? u : null` statements in one method scope, yielding CS0128 ("a local variable named 'u' is already defined"). 2. The recursive descent in `AddMapFilesOfInputTypeMethod` had no dedup guard, so when one input type had multiple fields of the same nested upload input type the `MapFilesFromType` method was emitted twice ("already defines a member 'MapFilesFromType...'"). The dedup `HashSet` is now threaded through the recursion and the scalar mapper reuses the already-unique `checkedVariable` name, so every upload field gets a unique local and each nested mapper is generated once. Adds a dedicated test class covering both an input type with multiple Upload scalar fields and an input type with multiple fields of the same nested upload input type; the generator output is Roslyn-compiled by the test helper, so both regressions are caught. Fixes ChilliCream/graphql-platform#9559 Fixes ChilliCream/graphql-platform#7852 --- .../Generators/OperationServiceGenerator.cs | 16 +- .../Integration/UploadScalarTest.Client.cs | 8 +- .../UploadScalar_InMemoryTest.Client.cs | 8 +- .../UploadMultipleFilesGeneratorTests.cs | 66 ++ ...ests.Operation_With_ComplexInputTypes.snap | 6 +- ...orTests.Operation_With_FirstNonUpload.snap | 2 +- ...torTests.Operation_With_LastNonUpload.snap | 2 +- ...ratorTests.Operation_With_UploadAsArg.snap | 12 +- ...peration_With_UploadInDeepInputObject.snap | 2 +- ...ts.Operation_With_UploadInInputObject.snap | 2 +- ...When_InputTypeHasMultipleUploadFields.snap | 718 +++++++++++++ ...asMultipleFieldsOfSameUploadInputType.snap | 942 ++++++++++++++++++ 12 files changed, 1755 insertions(+), 29 deletions(-) create mode 100644 src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/UploadMultipleFilesGeneratorTests.cs create mode 100644 src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/UploadMultipleFilesGeneratorTests.Generate_Should_CompileUniqueLocals_When_InputTypeHasMultipleUploadFields.snap create mode 100644 src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/UploadMultipleFilesGeneratorTests.Generate_Should_EmitSingleMapper_When_InputTypeHasMultipleFieldsOfSameUploadInputType.snap diff --git a/src/StrawberryShake/CodeGeneration/src/CodeGeneration.CSharp/Generators/OperationServiceGenerator.cs b/src/StrawberryShake/CodeGeneration/src/CodeGeneration.CSharp/Generators/OperationServiceGenerator.cs index 86b0f60af75..d78234252c6 100644 --- a/src/StrawberryShake/CodeGeneration/src/CodeGeneration.CSharp/Generators/OperationServiceGenerator.cs +++ b/src/StrawberryShake/CodeGeneration/src/CodeGeneration.CSharp/Generators/OperationServiceGenerator.cs @@ -584,10 +584,7 @@ private static void AddFileMapMethods( { if (argument.Type.NamedType() is InputObjectTypeDescriptor { HasUpload: true } type) { - if (processed.Add(argument.Type.NamedType().Name)) - { - AddMapFilesOfInputTypeMethod(classBuilder, type); - } + AddMapFilesOfInputTypeMethod(classBuilder, type, processed); } else if (argument.Type.NamedType() is not ScalarTypeDescriptor { Name: "Upload" }) { @@ -605,9 +602,10 @@ private static void AddFileMapMethods( private static void AddMapFilesOfInputTypeMethod( ClassBuilder builder, - InputObjectTypeDescriptor type) + InputObjectTypeDescriptor type, + HashSet processed) { - if (!type.HasUpload) + if (!type.HasUpload || !processed.Add(type.Name)) { return; } @@ -642,7 +640,7 @@ private static void AddMapFilesOfInputTypeMethod( if (field.Type.NamedType() is InputObjectTypeDescriptor nextType) { - AddMapFilesOfInputTypeMethod(builder, nextType); + AddMapFilesOfInputTypeMethod(builder, nextType, processed); } } } @@ -700,7 +698,9 @@ private static ICode BuildUploadFileMapper( .New() .SetMethodName(Files, "Add") .AddArgument(pathVariable) - .AddArgument($"{variable} is {TypeNames.Upload} u ? u : null")); + .AddArgument( + $"{variable} is {TypeNames.Upload} {checkedVariable} " + + $"? {checkedVariable} : null")); default: throw ThrowHelper.OperationServiceGenerator_HasNoUploadScalar(typeReference); diff --git a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/Integration/UploadScalarTest.Client.cs b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/Integration/UploadScalarTest.Client.cs index 037a9d77391..ddf70122c30 100644 --- a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/Integration/UploadScalarTest.Client.cs +++ b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/Integration/UploadScalarTest.Client.cs @@ -681,7 +681,7 @@ private TestUploadQuery(global::StrawberryShake.IOperationExecutor files) { - files.Add(path, value is global::StrawberryShake.Upload u ? u : null); + files.Add(path, value is global::StrawberryShake.Upload value_i ? value_i : null); } private void MapFilesFromArgumentList(global::System.String path, global::System.Collections.Generic.IReadOnlyList? value, global::System.Collections.Generic.Dictionary files) @@ -692,7 +692,7 @@ private void MapFilesFromArgumentList(global::System.String path, global::System foreach (var value_lt in value_i) { var path_lt = path + "." + (path_counter++); - files.Add(path_lt, value_lt is global::StrawberryShake.Upload u ? u : null); + files.Add(path_lt, value_lt is global::StrawberryShake.Upload value_lt_i ? value_lt_i : null); } } } @@ -711,7 +711,7 @@ private void MapFilesFromArgumentNested(global::System.String path, global::Syst foreach (var value_lt_lt in value_lt_i) { var path_lt_lt = path_lt + "." + (path_lt_counter++); - files.Add(path_lt_lt, value_lt_lt is global::StrawberryShake.Upload u ? u : null); + files.Add(path_lt_lt, value_lt_lt is global::StrawberryShake.Upload value_lt_lt_i ? value_lt_lt_i : null); } } } @@ -742,7 +742,7 @@ private void MapFilesFromTypeBazInput(global::System.String path, global::Strawb { var pathFile = path + ".file"; var valueFile = value.File; - files.Add(pathFile, valueFile is global::StrawberryShake.Upload u ? u : null); + files.Add(pathFile, valueFile is global::StrawberryShake.Upload valueFile_i ? valueFile_i : null); } private void MapFilesFromArgumentObject(global::System.String path, global::StrawberryShake.CodeGeneration.CSharp.Integration.UploadScalar.TestInput? value, global::System.Collections.Generic.Dictionary files) diff --git a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/Integration/UploadScalar_InMemoryTest.Client.cs b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/Integration/UploadScalar_InMemoryTest.Client.cs index d248e106f45..bd54cd13b9b 100644 --- a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/Integration/UploadScalar_InMemoryTest.Client.cs +++ b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/Integration/UploadScalar_InMemoryTest.Client.cs @@ -681,7 +681,7 @@ private TestUploadQuery(global::StrawberryShake.IOperationExecutor files) { - files.Add(path, value is global::StrawberryShake.Upload u ? u : null); + files.Add(path, value is global::StrawberryShake.Upload value_i ? value_i : null); } private void MapFilesFromArgumentList(global::System.String path, global::System.Collections.Generic.IReadOnlyList? value, global::System.Collections.Generic.Dictionary files) @@ -692,7 +692,7 @@ private void MapFilesFromArgumentList(global::System.String path, global::System foreach (var value_lt in value_i) { var path_lt = path + "." + (path_counter++); - files.Add(path_lt, value_lt is global::StrawberryShake.Upload u ? u : null); + files.Add(path_lt, value_lt is global::StrawberryShake.Upload value_lt_i ? value_lt_i : null); } } } @@ -711,7 +711,7 @@ private void MapFilesFromArgumentNested(global::System.String path, global::Syst foreach (var value_lt_lt in value_lt_i) { var path_lt_lt = path_lt + "." + (path_lt_counter++); - files.Add(path_lt_lt, value_lt_lt is global::StrawberryShake.Upload u ? u : null); + files.Add(path_lt_lt, value_lt_lt is global::StrawberryShake.Upload value_lt_lt_i ? value_lt_lt_i : null); } } } @@ -742,7 +742,7 @@ private void MapFilesFromTypeBazInput(global::System.String path, global::Strawb { var pathFile = path + ".file"; var valueFile = value.File; - files.Add(pathFile, valueFile is global::StrawberryShake.Upload u ? u : null); + files.Add(pathFile, valueFile is global::StrawberryShake.Upload valueFile_i ? valueFile_i : null); } private void MapFilesFromArgumentObject(global::System.String path, global::StrawberryShake.CodeGeneration.CSharp.Integration.UploadScalar_InMemory.TestInput? value, global::System.Collections.Generic.Dictionary files) diff --git a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/UploadMultipleFilesGeneratorTests.cs b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/UploadMultipleFilesGeneratorTests.cs new file mode 100644 index 00000000000..0e5e57c1bf0 --- /dev/null +++ b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/UploadMultipleFilesGeneratorTests.cs @@ -0,0 +1,66 @@ +using static StrawberryShake.CodeGeneration.CSharp.GeneratorTestHelper; + +namespace StrawberryShake.CodeGeneration.CSharp; + +public class UploadMultipleFilesGeneratorTests +{ + [Fact] + public void Generate_Should_CompileUniqueLocals_When_InputTypeHasMultipleUploadFields() + { + // arrange + // an input type with more than one Upload field forces the file mapper + // to emit several upload statements inside the same method scope. + + // act + assert + AssertResult( + @"query test($input: FileUpload!) { + upload(input: $input) + }", + @"type Query { + upload(input: FileUpload): String + } + + input FileUpload { + metadata: String! + file: Upload + file2: Upload + } + + scalar Upload + ", + "extend schema @key(fields: \"id\")"); + } + + [Fact] + public void Generate_Should_EmitSingleMapper_When_InputTypeHasMultipleFieldsOfSameUploadInputType() + { + // arrange + // an input type has two fields that point to the same nested upload input + // type, so the file mapper for that nested type must only be generated once. + + // act + assert + AssertResult( + @"query test($input: CreateTaskInput!) { + upload(input: $input) + }", + @"type Query { + upload(input: CreateTaskInput): String + } + + input CreateTaskInput { + title: String + uploadOne: FileUpload + uploadTwo: FileUpload + } + + input FileUpload { + metadata: String! + file: Upload + file2: Upload + } + + scalar Upload + ", + "extend schema @key(fields: \"id\")"); + } +} diff --git a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/InputGeneratorTests.Operation_With_ComplexInputTypes.snap b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/InputGeneratorTests.Operation_With_ComplexInputTypes.snap index b06b4c408fe..c03aff2928f 100644 --- a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/InputGeneratorTests.Operation_With_ComplexInputTypes.snap +++ b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/InputGeneratorTests.Operation_With_ComplexInputTypes.snap @@ -787,7 +787,7 @@ namespace Foo.Bar { var pathProfilePicture = path + ".profilePicture"; var valueProfilePicture = value.ProfilePicture; - files.Add(pathProfilePicture, valueProfilePicture is global::StrawberryShake.Upload u ? u : null); + files.Add(pathProfilePicture, valueProfilePicture is global::StrawberryShake.Upload valueProfilePicture_i ? valueProfilePicture_i : null); var pathPhotos = path + ".photos"; var valuePhotos = value.Photos; if (valuePhotos is { } valuePhotos_i) @@ -808,7 +808,7 @@ namespace Foo.Bar { var pathData = path + ".data"; var valueData = value.Data; - files.Add(pathData, valueData is global::StrawberryShake.Upload u ? u : null); + files.Add(pathData, valueData is global::StrawberryShake.Upload valueData_i ? valueData_i : null); var pathMetadata = path + ".metadata"; var valueMetadata = value.Metadata; if (valueMetadata is { } valueMetadata_i) @@ -821,7 +821,7 @@ namespace Foo.Bar { var pathThumbnail = path + ".thumbnail"; var valueThumbnail = value.Thumbnail; - files.Add(pathThumbnail, valueThumbnail is global::StrawberryShake.Upload u ? u : null); + files.Add(pathThumbnail, valueThumbnail is global::StrawberryShake.Upload valueThumbnail_i ? valueThumbnail_i : null); } private void MapFilesFromArgumentInput(global::System.String path, global::Foo.Bar.User value, global::System.Collections.Generic.Dictionary files) diff --git a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/InputGeneratorTests.Operation_With_FirstNonUpload.snap b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/InputGeneratorTests.Operation_With_FirstNonUpload.snap index 88ee76b5ec1..f315d519f6a 100644 --- a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/InputGeneratorTests.Operation_With_FirstNonUpload.snap +++ b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/InputGeneratorTests.Operation_With_FirstNonUpload.snap @@ -184,7 +184,7 @@ namespace Foo.Bar private void MapFilesFromArgumentUpload(global::System.String path, global::StrawberryShake.Upload value, global::System.Collections.Generic.Dictionary files) { - files.Add(path, value is global::StrawberryShake.Upload u ? u : null); + files.Add(path, value is global::StrawberryShake.Upload value_i ? value_i : null); } public global::System.IObservable> Watch(global::System.String @string, global::StrawberryShake.Upload upload, global::StrawberryShake.ExecutionStrategy? strategy = null) diff --git a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/InputGeneratorTests.Operation_With_LastNonUpload.snap b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/InputGeneratorTests.Operation_With_LastNonUpload.snap index e493d05d86a..930c29aa1b9 100644 --- a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/InputGeneratorTests.Operation_With_LastNonUpload.snap +++ b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/InputGeneratorTests.Operation_With_LastNonUpload.snap @@ -184,7 +184,7 @@ namespace Foo.Bar private void MapFilesFromArgumentUpload(global::System.String path, global::StrawberryShake.Upload value, global::System.Collections.Generic.Dictionary files) { - files.Add(path, value is global::StrawberryShake.Upload u ? u : null); + files.Add(path, value is global::StrawberryShake.Upload value_i ? value_i : null); } public global::System.IObservable> Watch(global::StrawberryShake.Upload upload, global::System.String @string, global::StrawberryShake.ExecutionStrategy? strategy = null) diff --git a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/InputGeneratorTests.Operation_With_UploadAsArg.snap b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/InputGeneratorTests.Operation_With_UploadAsArg.snap index d8c9d97e419..934476396e8 100644 --- a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/InputGeneratorTests.Operation_With_UploadAsArg.snap +++ b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/InputGeneratorTests.Operation_With_UploadAsArg.snap @@ -209,12 +209,12 @@ namespace Foo.Bar private void MapFilesFromArgumentUpload(global::System.String path, global::StrawberryShake.Upload value, global::System.Collections.Generic.Dictionary files) { - files.Add(path, value is global::StrawberryShake.Upload u ? u : null); + files.Add(path, value is global::StrawberryShake.Upload value_i ? value_i : null); } private void MapFilesFromArgumentUploadNullable(global::System.String path, global::StrawberryShake.Upload? value, global::System.Collections.Generic.Dictionary files) { - files.Add(path, value is global::StrawberryShake.Upload u ? u : null); + files.Add(path, value is global::StrawberryShake.Upload value_i ? value_i : null); } private void MapFilesFromArgumentList(global::System.String path, global::System.Collections.Generic.IReadOnlyList value, global::System.Collections.Generic.Dictionary files) @@ -225,7 +225,7 @@ namespace Foo.Bar foreach (var value_lt in value_i) { var path_lt = path + "." + (path_counter++); - files.Add(path_lt, value_lt is global::StrawberryShake.Upload u ? u : null); + files.Add(path_lt, value_lt is global::StrawberryShake.Upload value_lt_i ? value_lt_i : null); } } } @@ -238,7 +238,7 @@ namespace Foo.Bar foreach (var value_lt in value_i) { var path_lt = path + "." + (path_counter++); - files.Add(path_lt, value_lt is global::StrawberryShake.Upload u ? u : null); + files.Add(path_lt, value_lt is global::StrawberryShake.Upload value_lt_i ? value_lt_i : null); } } } @@ -257,7 +257,7 @@ namespace Foo.Bar foreach (var value_lt_lt in value_lt_i) { var path_lt_lt = path_lt + "." + (path_lt_counter++); - files.Add(path_lt_lt, value_lt_lt is global::StrawberryShake.Upload u ? u : null); + files.Add(path_lt_lt, value_lt_lt is global::StrawberryShake.Upload value_lt_lt_i ? value_lt_lt_i : null); } } } @@ -278,7 +278,7 @@ namespace Foo.Bar foreach (var value_lt_lt in value_lt_i) { var path_lt_lt = path_lt + "." + (path_lt_counter++); - files.Add(path_lt_lt, value_lt_lt is global::StrawberryShake.Upload u ? u : null); + files.Add(path_lt_lt, value_lt_lt is global::StrawberryShake.Upload value_lt_lt_i ? value_lt_lt_i : null); } } } diff --git a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/InputGeneratorTests.Operation_With_UploadInDeepInputObject.snap b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/InputGeneratorTests.Operation_With_UploadInDeepInputObject.snap index 7b147143138..1622868c7d1 100644 --- a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/InputGeneratorTests.Operation_With_UploadInDeepInputObject.snap +++ b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/InputGeneratorTests.Operation_With_UploadInDeepInputObject.snap @@ -668,7 +668,7 @@ namespace Foo.Bar { var pathFoo = path + ".foo"; var valueFoo = value.Foo; - files.Add(pathFoo, valueFoo is global::StrawberryShake.Upload u ? u : null); + files.Add(pathFoo, valueFoo is global::StrawberryShake.Upload valueFoo_i ? valueFoo_i : null); } private void MapFilesFromArgumentInput(global::System.String path, global::Foo.Bar.Test value, global::System.Collections.Generic.Dictionary files) diff --git a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/InputGeneratorTests.Operation_With_UploadInInputObject.snap b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/InputGeneratorTests.Operation_With_UploadInInputObject.snap index 6238a99a429..9341c3839ae 100644 --- a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/InputGeneratorTests.Operation_With_UploadInInputObject.snap +++ b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/InputGeneratorTests.Operation_With_UploadInInputObject.snap @@ -293,7 +293,7 @@ namespace Foo.Bar { var pathFoo = path + ".foo"; var valueFoo = value.Foo; - files.Add(pathFoo, valueFoo is global::StrawberryShake.Upload u ? u : null); + files.Add(pathFoo, valueFoo is global::StrawberryShake.Upload valueFoo_i ? valueFoo_i : null); } private void MapFilesFromArgumentInput(global::System.String path, global::Foo.Bar.Test value, global::System.Collections.Generic.Dictionary files) diff --git a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/UploadMultipleFilesGeneratorTests.Generate_Should_CompileUniqueLocals_When_InputTypeHasMultipleUploadFields.snap b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/UploadMultipleFilesGeneratorTests.Generate_Should_CompileUniqueLocals_When_InputTypeHasMultipleUploadFields.snap new file mode 100644 index 00000000000..8b06452d8f7 --- /dev/null +++ b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/UploadMultipleFilesGeneratorTests.Generate_Should_CompileUniqueLocals_When_InputTypeHasMultipleUploadFields.snap @@ -0,0 +1,718 @@ +// 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 TestResult : global::System.IEquatable, ITestResult + { + public TestResult(global::System.String? upload) + { + Upload = upload; + } + + public global::System.String? Upload { get; } + + public virtual global::System.Boolean Equals(TestResult? other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (other.GetType() != GetType()) + { + return false; + } + + return (((Upload is null && other.Upload is null) || Upload != null && Upload.Equals(other.Upload))); + } + + 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((TestResult)obj); + } + + public override global::System.Int32 GetHashCode() + { + unchecked + { + int hash = 5; + if (Upload != null) + { + hash ^= 397 * Upload.GetHashCode(); + } + + return hash; + } + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface ITestResult + { + public global::System.String? Upload { get; } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.InputValueFormatterGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class FileUploadInputValueFormatter : global::StrawberryShake.Serialization.IInputObjectFormatter + { + private global::StrawberryShake.Serialization.IInputValueFormatter _stringFormatter = default !; + private global::StrawberryShake.Serialization.IInputValueFormatter _uploadFormatter = default !; + public global::System.String TypeName => "FileUpload"; + + public void Initialize(global::StrawberryShake.Serialization.ISerializerResolver serializerResolver) + { + _stringFormatter = serializerResolver.GetInputValueFormatter("String"); + _uploadFormatter = serializerResolver.GetInputValueFormatter("Upload"); + } + + public global::System.Object? Format(global::System.Object? runtimeValue) + { + if (runtimeValue is null) + { + return null; + } + + var input = runtimeValue as global::Foo.Bar.FileUpload; + var inputInfo = runtimeValue as global::Foo.Bar.State.IFileUploadInfo; + if (input is null || inputInfo is null) + { + throw new global::System.ArgumentException(nameof(runtimeValue)); + } + + var fields = new global::System.Collections.Generic.List>(); + if (inputInfo.IsMetadataSet) + { + fields.Add(new global::System.Collections.Generic.KeyValuePair("metadata", FormatMetadata(input.Metadata))); + } + + if (inputInfo.IsFileSet) + { + fields.Add(new global::System.Collections.Generic.KeyValuePair("file", FormatFile(input.File))); + } + + if (inputInfo.IsFile2Set) + { + fields.Add(new global::System.Collections.Generic.KeyValuePair("file2", FormatFile2(input.File2))); + } + + return fields; + } + + private global::System.Object? FormatMetadata(global::System.String input) + { + if (input is null) + { + throw new global::System.ArgumentNullException(nameof(input)); + } + + return _stringFormatter.Format(input); + } + + private global::System.Object? FormatFile(global::StrawberryShake.Upload? input) + { + if (input is null) + { + return input; + } + else + { + return _uploadFormatter.Format(input); + } + } + + private global::System.Object? FormatFile2(global::StrawberryShake.Upload? input) + { + if (input is null) + { + return input; + } + else + { + return _uploadFormatter.Format(input); + } + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.InputTypeGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "0.0.0.0")] + public partial class FileUpload : global::Foo.Bar.State.IFileUploadInfo, global::System.IEquatable + { + 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((FileUpload)obj); + } + + public virtual global::System.Boolean Equals(FileUpload? other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (other.GetType() != GetType()) + { + return false; + } + + return (Metadata.Equals(other.Metadata)) && ((File is null && other.File is null) || File != null && File.Equals(other.File)) && ((File2 is null && other.File2 is null) || File2 != null && File2.Equals(other.File2)); + } + + public override global::System.Int32 GetHashCode() + { + unchecked + { + int hash = 5; + hash ^= 397 * Metadata.GetHashCode(); + if (File != null) + { + hash ^= 397 * File.GetHashCode(); + } + + if (File2 != null) + { + hash ^= 397 * File2.GetHashCode(); + } + + return hash; + } + } + + private global::System.String _value_metadata = default !; + private global::System.Boolean _set_metadata; + private global::StrawberryShake.Upload? _value_file; + private global::System.Boolean _set_file; + private global::StrawberryShake.Upload? _value_file2; + private global::System.Boolean _set_file2; + public global::System.String Metadata + { + get => _value_metadata; + set + { + _set_metadata = true; + _value_metadata = value; + } + } + + global::System.Boolean global::Foo.Bar.State.IFileUploadInfo.IsMetadataSet => _set_metadata; + + public global::StrawberryShake.Upload? File + { + get => _value_file; + set + { + _set_file = true; + _value_file = value; + } + } + + global::System.Boolean global::Foo.Bar.State.IFileUploadInfo.IsFileSet => _set_file; + + public global::StrawberryShake.Upload? File2 + { + get => _value_file2; + set + { + _set_file2 = true; + _value_file2 = value; + } + } + + global::System.Boolean global::Foo.Bar.State.IFileUploadInfo.IsFile2Set => _set_file2; + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.OperationDocumentGenerator + /// + /// Represents the operation service of the Test GraphQL operation + /// + /// query Test($input: FileUpload!) { + /// upload(input: $input) + /// } + /// + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class TestQueryDocument : global::StrawberryShake.IDocument + { + private TestQueryDocument() + { + } + + public static TestQueryDocument Instance { get; } = new TestQueryDocument(); + public global::StrawberryShake.OperationKind Kind => global::StrawberryShake.OperationKind.Query; + public global::System.ReadOnlySpan Body => "query Test($input: FileUpload!) { upload(input: $input) }"u8; + public global::StrawberryShake.DocumentHash Hash { get; } = new global::StrawberryShake.DocumentHash("sha1Hash", "e32a387c40445e5d43e06a80c7b82b6f99eeaafb"); + + 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 Test GraphQL operation + /// + /// query Test($input: FileUpload!) { + /// upload(input: $input) + /// } + /// + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class TestQuery : global::Foo.Bar.ITestQuery + { + private readonly global::StrawberryShake.IOperationExecutor _operationExecutor; + private readonly global::StrawberryShake.Serialization.IInputValueFormatter _fileUploadFormatter; + private readonly global::System.Collections.Immutable.ImmutableArray> _configure = global::System.Collections.Immutable.ImmutableArray>.Empty; + public TestQuery(global::StrawberryShake.IOperationExecutor operationExecutor, global::StrawberryShake.Serialization.ISerializerResolver serializerResolver) + { + _operationExecutor = operationExecutor ?? throw new global::System.ArgumentNullException(nameof(operationExecutor)); + _fileUploadFormatter = serializerResolver.GetInputValueFormatter("FileUpload"); + } + + private TestQuery(global::StrawberryShake.IOperationExecutor operationExecutor, global::System.Collections.Immutable.ImmutableArray> configure, global::StrawberryShake.Serialization.IInputValueFormatter fileUploadFormatter) + { + _operationExecutor = operationExecutor; + _configure = configure; + _fileUploadFormatter = fileUploadFormatter; + } + + global::System.Type global::StrawberryShake.IOperationRequestFactory.ResultType => typeof(ITestResult); + + public global::Foo.Bar.ITestQuery With(global::System.Action configure) + { + return new global::Foo.Bar.TestQuery(_operationExecutor, _configure.Add(configure), _fileUploadFormatter); + } + + public global::Foo.Bar.ITestQuery WithRequestUri(global::System.Uri requestUri) + { + return With(r => r.ContextData["StrawberryShake.Transport.Http.HttpConnection.RequestUri"] = requestUri); + } + + public global::Foo.Bar.ITestQuery 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::Foo.Bar.FileUpload input, global::System.Threading.CancellationToken cancellationToken = default) + { + var request = CreateRequest(input); + foreach (var configure in _configure) + { + configure(request); + } + + return await _operationExecutor.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + } + + private void MapFilesFromTypeFileUpload(global::System.String path, global::Foo.Bar.FileUpload value, global::System.Collections.Generic.Dictionary files) + { + var pathFile = path + ".file"; + var valueFile = value.File; + files.Add(pathFile, valueFile is global::StrawberryShake.Upload valueFile_i ? valueFile_i : null); + var pathFile2 = path + ".file2"; + var valueFile2 = value.File2; + files.Add(pathFile2, valueFile2 is global::StrawberryShake.Upload valueFile2_i ? valueFile2_i : null); + } + + private void MapFilesFromArgumentInput(global::System.String path, global::Foo.Bar.FileUpload value, global::System.Collections.Generic.Dictionary files) + { + if (value is { } value_i) + { + MapFilesFromTypeFileUpload(path, value_i, files); + } + } + + public global::System.IObservable> Watch(global::Foo.Bar.FileUpload input, global::StrawberryShake.ExecutionStrategy? strategy = null) + { + var request = CreateRequest(input); + return _operationExecutor.Watch(request, strategy); + } + + private global::StrawberryShake.OperationRequest CreateRequest(global::Foo.Bar.FileUpload input) + { + var variables = new global::System.Collections.Generic.Dictionary(); + variables.Add("input", FormatInput(input)); + var files = new global::System.Collections.Generic.Dictionary(); + MapFilesFromArgumentInput("variables.input", input, files); + return CreateRequest(variables, files); + } + + private global::StrawberryShake.OperationRequest CreateRequest(global::System.Collections.Generic.IReadOnlyDictionary? variables, global::System.Collections.Generic.Dictionary files) + { + return new global::StrawberryShake.OperationRequest(id: TestQueryDocument.Instance.Hash.Value, name: "Test", document: TestQueryDocument.Instance, strategy: global::StrawberryShake.RequestStrategy.Default, files: files, variables: variables); + } + + private global::System.Object? FormatInput(global::Foo.Bar.FileUpload value) + { + if (value is null) + { + throw new global::System.ArgumentNullException(nameof(value)); + } + + return _fileUploadFormatter.Format(value); + } + + global::StrawberryShake.OperationRequest global::StrawberryShake.IOperationRequestFactory.Create(global::System.Collections.Generic.IReadOnlyDictionary? variables) + { + return CreateRequest(variables!, new global::System.Collections.Generic.Dictionary()); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.OperationServiceInterfaceGenerator + /// + /// Represents the operation service of the Test GraphQL operation + /// + /// query Test($input: FileUpload!) { + /// upload(input: $input) + /// } + /// + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface ITestQuery : global::StrawberryShake.IOperationRequestFactory + { + global::Foo.Bar.ITestQuery With(global::System.Action configure); + global::Foo.Bar.ITestQuery WithRequestUri(global::System.Uri requestUri); + global::Foo.Bar.ITestQuery WithHttpClient(global::System.Net.Http.HttpClient httpClient); + global::System.Threading.Tasks.Task> ExecuteAsync(global::Foo.Bar.FileUpload input, global::System.Threading.CancellationToken cancellationToken = default); + global::System.IObservable> Watch(global::Foo.Bar.FileUpload input, 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.ITestQuery _test; + public FooClient(global::Foo.Bar.ITestQuery test) + { + _test = test ?? throw new global::System.ArgumentNullException(nameof(test)); + } + + public static global::System.String ClientName => "FooClient"; + public global::Foo.Bar.ITestQuery Test => _test; + } + + // 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.ITestQuery Test { get; } + } +} + +namespace Foo.Bar.State +{ + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultDataFactoryGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class TestResultFactory : global::StrawberryShake.IOperationResultDataFactory + { + private readonly global::StrawberryShake.IEntityStore _entityStore; + public TestResultFactory(global::StrawberryShake.IEntityStore entityStore) + { + _entityStore = entityStore ?? throw new global::System.ArgumentNullException(nameof(entityStore)); + } + + global::System.Type global::StrawberryShake.IOperationResultDataFactory.ResultType => typeof(global::Foo.Bar.ITestResult); + + public TestResult Create(global::StrawberryShake.IOperationResultDataInfo dataInfo, global::StrawberryShake.IEntityStoreSnapshot? snapshot = null) + { + if (snapshot is null) + { + snapshot = _entityStore.CurrentSnapshot; + } + + if (dataInfo is TestResultInfo info) + { + return new TestResult(info.Upload); + } + + throw new global::System.ArgumentException("TestResultInfo expected."); + } + + 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 TestResultInfo : global::StrawberryShake.IOperationResultDataInfo + { + private readonly global::System.Collections.Generic.IReadOnlyCollection _entityIds; + private readonly global::System.UInt64 _version; + public TestResultInfo(global::System.String? upload, global::System.Collections.Generic.IReadOnlyCollection entityIds, global::System.UInt64 version) + { + Upload = upload; + _entityIds = entityIds ?? throw new global::System.ArgumentNullException(nameof(entityIds)); + _version = version; + } + + public global::System.String? Upload { 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 TestResultInfo(Upload, _entityIds, version); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.InputTypeStateInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "0.0.0.0")] + internal interface IFileUploadInfo + { + global::System.Boolean IsMetadataSet { get; } + + global::System.Boolean IsFileSet { get; } + + global::System.Boolean IsFile2Set { get; } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.JsonResultBuilderGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class TestBuilder : global::StrawberryShake.OperationResultBuilder + { + private readonly global::StrawberryShake.IEntityStore _entityStore; + private readonly global::StrawberryShake.IEntityIdSerializer _idSerializer; + private readonly global::StrawberryShake.Serialization.ILeafValueParser _stringParser; + private readonly global::StrawberryShake.Serialization.ILeafValueParser _uploadParser; + public TestBuilder(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."); + _uploadParser = serializerResolver.GetLeafValueParser("Upload") ?? throw new global::System.ArgumentException("No serializer for type `Upload` 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 !; + _entityStore.Update(session => + { + snapshot = session.CurrentSnapshot; + }); + return new TestResultInfo(Deserialize_String(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "upload")), entityIds, snapshot.Version); + } + + 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.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 + { + _ => throw new global::System.NotSupportedException()}; + } + + public global::System.String Format(global::StrawberryShake.EntityId entityId) + { + return entityId.Name switch + { + _ => throw new global::System.NotSupportedException()}; + } + } + + // 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(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); + 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.TestResultFactory>(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.TestBuilder>(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__/UploadMultipleFilesGeneratorTests.Generate_Should_EmitSingleMapper_When_InputTypeHasMultipleFieldsOfSameUploadInputType.snap b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/UploadMultipleFilesGeneratorTests.Generate_Should_EmitSingleMapper_When_InputTypeHasMultipleFieldsOfSameUploadInputType.snap new file mode 100644 index 00000000000..fcea3f8ce32 --- /dev/null +++ b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/__snapshots__/UploadMultipleFilesGeneratorTests.Generate_Should_EmitSingleMapper_When_InputTypeHasMultipleFieldsOfSameUploadInputType.snap @@ -0,0 +1,942 @@ +// 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 TestResult : global::System.IEquatable, ITestResult + { + public TestResult(global::System.String? upload) + { + Upload = upload; + } + + public global::System.String? Upload { get; } + + public virtual global::System.Boolean Equals(TestResult? other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (other.GetType() != GetType()) + { + return false; + } + + return (((Upload is null && other.Upload is null) || Upload != null && Upload.Equals(other.Upload))); + } + + 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((TestResult)obj); + } + + public override global::System.Int32 GetHashCode() + { + unchecked + { + int hash = 5; + if (Upload != null) + { + hash ^= 397 * Upload.GetHashCode(); + } + + return hash; + } + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface ITestResult + { + public global::System.String? Upload { get; } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.InputValueFormatterGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class CreateTaskInputInputValueFormatter : global::StrawberryShake.Serialization.IInputObjectFormatter + { + private global::StrawberryShake.Serialization.IInputValueFormatter _stringFormatter = default !; + private global::StrawberryShake.Serialization.IInputValueFormatter _fileUploadFormatter = default !; + public global::System.String TypeName => "CreateTaskInput"; + + public void Initialize(global::StrawberryShake.Serialization.ISerializerResolver serializerResolver) + { + _stringFormatter = serializerResolver.GetInputValueFormatter("String"); + _fileUploadFormatter = serializerResolver.GetInputValueFormatter("FileUpload"); + } + + public global::System.Object? Format(global::System.Object? runtimeValue) + { + if (runtimeValue is null) + { + return null; + } + + var input = runtimeValue as global::Foo.Bar.CreateTaskInput; + var inputInfo = runtimeValue as global::Foo.Bar.State.ICreateTaskInputInfo; + if (input is null || inputInfo is null) + { + throw new global::System.ArgumentException(nameof(runtimeValue)); + } + + var fields = new global::System.Collections.Generic.List>(); + if (inputInfo.IsTitleSet) + { + fields.Add(new global::System.Collections.Generic.KeyValuePair("title", FormatTitle(input.Title))); + } + + if (inputInfo.IsUploadOneSet) + { + fields.Add(new global::System.Collections.Generic.KeyValuePair("uploadOne", FormatUploadOne(input.UploadOne))); + } + + if (inputInfo.IsUploadTwoSet) + { + fields.Add(new global::System.Collections.Generic.KeyValuePair("uploadTwo", FormatUploadTwo(input.UploadTwo))); + } + + return fields; + } + + private global::System.Object? FormatTitle(global::System.String? input) + { + if (input is null) + { + return input; + } + else + { + return _stringFormatter.Format(input); + } + } + + private global::System.Object? FormatUploadOne(global::Foo.Bar.FileUpload? input) + { + if (input is null) + { + return input; + } + else + { + return _fileUploadFormatter.Format(input); + } + } + + private global::System.Object? FormatUploadTwo(global::Foo.Bar.FileUpload? input) + { + if (input is null) + { + return input; + } + else + { + return _fileUploadFormatter.Format(input); + } + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.InputTypeGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "0.0.0.0")] + public partial class CreateTaskInput : global::Foo.Bar.State.ICreateTaskInputInfo, global::System.IEquatable + { + 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((CreateTaskInput)obj); + } + + public virtual global::System.Boolean Equals(CreateTaskInput? other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (other.GetType() != GetType()) + { + return false; + } + + return (((Title is null && other.Title is null) || Title != null && Title.Equals(other.Title))) && ((UploadOne is null && other.UploadOne is null) || UploadOne != null && UploadOne.Equals(other.UploadOne)) && ((UploadTwo is null && other.UploadTwo is null) || UploadTwo != null && UploadTwo.Equals(other.UploadTwo)); + } + + public override global::System.Int32 GetHashCode() + { + unchecked + { + int hash = 5; + if (Title != null) + { + hash ^= 397 * Title.GetHashCode(); + } + + if (UploadOne != null) + { + hash ^= 397 * UploadOne.GetHashCode(); + } + + if (UploadTwo != null) + { + hash ^= 397 * UploadTwo.GetHashCode(); + } + + return hash; + } + } + + private global::System.String? _value_title; + private global::System.Boolean _set_title; + private global::Foo.Bar.FileUpload? _value_uploadOne; + private global::System.Boolean _set_uploadOne; + private global::Foo.Bar.FileUpload? _value_uploadTwo; + private global::System.Boolean _set_uploadTwo; + public global::System.String? Title + { + get => _value_title; + set + { + _set_title = true; + _value_title = value; + } + } + + global::System.Boolean global::Foo.Bar.State.ICreateTaskInputInfo.IsTitleSet => _set_title; + + public global::Foo.Bar.FileUpload? UploadOne + { + get => _value_uploadOne; + set + { + _set_uploadOne = true; + _value_uploadOne = value; + } + } + + global::System.Boolean global::Foo.Bar.State.ICreateTaskInputInfo.IsUploadOneSet => _set_uploadOne; + + public global::Foo.Bar.FileUpload? UploadTwo + { + get => _value_uploadTwo; + set + { + _set_uploadTwo = true; + _value_uploadTwo = value; + } + } + + global::System.Boolean global::Foo.Bar.State.ICreateTaskInputInfo.IsUploadTwoSet => _set_uploadTwo; + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.InputValueFormatterGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class FileUploadInputValueFormatter : global::StrawberryShake.Serialization.IInputObjectFormatter + { + private global::StrawberryShake.Serialization.IInputValueFormatter _stringFormatter = default !; + private global::StrawberryShake.Serialization.IInputValueFormatter _uploadFormatter = default !; + public global::System.String TypeName => "FileUpload"; + + public void Initialize(global::StrawberryShake.Serialization.ISerializerResolver serializerResolver) + { + _stringFormatter = serializerResolver.GetInputValueFormatter("String"); + _uploadFormatter = serializerResolver.GetInputValueFormatter("Upload"); + } + + public global::System.Object? Format(global::System.Object? runtimeValue) + { + if (runtimeValue is null) + { + return null; + } + + var input = runtimeValue as global::Foo.Bar.FileUpload; + var inputInfo = runtimeValue as global::Foo.Bar.State.IFileUploadInfo; + if (input is null || inputInfo is null) + { + throw new global::System.ArgumentException(nameof(runtimeValue)); + } + + var fields = new global::System.Collections.Generic.List>(); + if (inputInfo.IsMetadataSet) + { + fields.Add(new global::System.Collections.Generic.KeyValuePair("metadata", FormatMetadata(input.Metadata))); + } + + if (inputInfo.IsFileSet) + { + fields.Add(new global::System.Collections.Generic.KeyValuePair("file", FormatFile(input.File))); + } + + if (inputInfo.IsFile2Set) + { + fields.Add(new global::System.Collections.Generic.KeyValuePair("file2", FormatFile2(input.File2))); + } + + return fields; + } + + private global::System.Object? FormatMetadata(global::System.String input) + { + if (input is null) + { + throw new global::System.ArgumentNullException(nameof(input)); + } + + return _stringFormatter.Format(input); + } + + private global::System.Object? FormatFile(global::StrawberryShake.Upload? input) + { + if (input is null) + { + return input; + } + else + { + return _uploadFormatter.Format(input); + } + } + + private global::System.Object? FormatFile2(global::StrawberryShake.Upload? input) + { + if (input is null) + { + return input; + } + else + { + return _uploadFormatter.Format(input); + } + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.InputTypeGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "0.0.0.0")] + public partial class FileUpload : global::Foo.Bar.State.IFileUploadInfo, global::System.IEquatable + { + 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((FileUpload)obj); + } + + public virtual global::System.Boolean Equals(FileUpload? other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (other.GetType() != GetType()) + { + return false; + } + + return (Metadata.Equals(other.Metadata)) && ((File is null && other.File is null) || File != null && File.Equals(other.File)) && ((File2 is null && other.File2 is null) || File2 != null && File2.Equals(other.File2)); + } + + public override global::System.Int32 GetHashCode() + { + unchecked + { + int hash = 5; + hash ^= 397 * Metadata.GetHashCode(); + if (File != null) + { + hash ^= 397 * File.GetHashCode(); + } + + if (File2 != null) + { + hash ^= 397 * File2.GetHashCode(); + } + + return hash; + } + } + + private global::System.String _value_metadata = default !; + private global::System.Boolean _set_metadata; + private global::StrawberryShake.Upload? _value_file; + private global::System.Boolean _set_file; + private global::StrawberryShake.Upload? _value_file2; + private global::System.Boolean _set_file2; + public global::System.String Metadata + { + get => _value_metadata; + set + { + _set_metadata = true; + _value_metadata = value; + } + } + + global::System.Boolean global::Foo.Bar.State.IFileUploadInfo.IsMetadataSet => _set_metadata; + + public global::StrawberryShake.Upload? File + { + get => _value_file; + set + { + _set_file = true; + _value_file = value; + } + } + + global::System.Boolean global::Foo.Bar.State.IFileUploadInfo.IsFileSet => _set_file; + + public global::StrawberryShake.Upload? File2 + { + get => _value_file2; + set + { + _set_file2 = true; + _value_file2 = value; + } + } + + global::System.Boolean global::Foo.Bar.State.IFileUploadInfo.IsFile2Set => _set_file2; + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.OperationDocumentGenerator + /// + /// Represents the operation service of the Test GraphQL operation + /// + /// query Test($input: CreateTaskInput!) { + /// upload(input: $input) + /// } + /// + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class TestQueryDocument : global::StrawberryShake.IDocument + { + private TestQueryDocument() + { + } + + public static TestQueryDocument Instance { get; } = new TestQueryDocument(); + public global::StrawberryShake.OperationKind Kind => global::StrawberryShake.OperationKind.Query; + public global::System.ReadOnlySpan Body => "query Test($input: CreateTaskInput!) { upload(input: $input) }"u8; + public global::StrawberryShake.DocumentHash Hash { get; } = new global::StrawberryShake.DocumentHash("sha1Hash", "bfaadbd1e2d1ca65b95f012233915e01b3b5c185"); + + 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 Test GraphQL operation + /// + /// query Test($input: CreateTaskInput!) { + /// upload(input: $input) + /// } + /// + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class TestQuery : global::Foo.Bar.ITestQuery + { + private readonly global::StrawberryShake.IOperationExecutor _operationExecutor; + private readonly global::StrawberryShake.Serialization.IInputValueFormatter _createTaskInputFormatter; + private readonly global::System.Collections.Immutable.ImmutableArray> _configure = global::System.Collections.Immutable.ImmutableArray>.Empty; + public TestQuery(global::StrawberryShake.IOperationExecutor operationExecutor, global::StrawberryShake.Serialization.ISerializerResolver serializerResolver) + { + _operationExecutor = operationExecutor ?? throw new global::System.ArgumentNullException(nameof(operationExecutor)); + _createTaskInputFormatter = serializerResolver.GetInputValueFormatter("CreateTaskInput"); + } + + private TestQuery(global::StrawberryShake.IOperationExecutor operationExecutor, global::System.Collections.Immutable.ImmutableArray> configure, global::StrawberryShake.Serialization.IInputValueFormatter createTaskInputFormatter) + { + _operationExecutor = operationExecutor; + _configure = configure; + _createTaskInputFormatter = createTaskInputFormatter; + } + + global::System.Type global::StrawberryShake.IOperationRequestFactory.ResultType => typeof(ITestResult); + + public global::Foo.Bar.ITestQuery With(global::System.Action configure) + { + return new global::Foo.Bar.TestQuery(_operationExecutor, _configure.Add(configure), _createTaskInputFormatter); + } + + public global::Foo.Bar.ITestQuery WithRequestUri(global::System.Uri requestUri) + { + return With(r => r.ContextData["StrawberryShake.Transport.Http.HttpConnection.RequestUri"] = requestUri); + } + + public global::Foo.Bar.ITestQuery 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::Foo.Bar.CreateTaskInput input, global::System.Threading.CancellationToken cancellationToken = default) + { + var request = CreateRequest(input); + foreach (var configure in _configure) + { + configure(request); + } + + return await _operationExecutor.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + } + + private void MapFilesFromTypeCreateTaskInput(global::System.String path, global::Foo.Bar.CreateTaskInput value, global::System.Collections.Generic.Dictionary files) + { + var pathUploadOne = path + ".uploadOne"; + var valueUploadOne = value.UploadOne; + if (valueUploadOne is { } valueUploadOne_i) + { + MapFilesFromTypeFileUpload(pathUploadOne, valueUploadOne_i, files); + } + + var pathUploadTwo = path + ".uploadTwo"; + var valueUploadTwo = value.UploadTwo; + if (valueUploadTwo is { } valueUploadTwo_i) + { + MapFilesFromTypeFileUpload(pathUploadTwo, valueUploadTwo_i, files); + } + } + + private void MapFilesFromTypeFileUpload(global::System.String path, global::Foo.Bar.FileUpload value, global::System.Collections.Generic.Dictionary files) + { + var pathFile = path + ".file"; + var valueFile = value.File; + files.Add(pathFile, valueFile is global::StrawberryShake.Upload valueFile_i ? valueFile_i : null); + var pathFile2 = path + ".file2"; + var valueFile2 = value.File2; + files.Add(pathFile2, valueFile2 is global::StrawberryShake.Upload valueFile2_i ? valueFile2_i : null); + } + + private void MapFilesFromArgumentInput(global::System.String path, global::Foo.Bar.CreateTaskInput value, global::System.Collections.Generic.Dictionary files) + { + if (value is { } value_i) + { + MapFilesFromTypeCreateTaskInput(path, value_i, files); + } + } + + public global::System.IObservable> Watch(global::Foo.Bar.CreateTaskInput input, global::StrawberryShake.ExecutionStrategy? strategy = null) + { + var request = CreateRequest(input); + return _operationExecutor.Watch(request, strategy); + } + + private global::StrawberryShake.OperationRequest CreateRequest(global::Foo.Bar.CreateTaskInput input) + { + var variables = new global::System.Collections.Generic.Dictionary(); + variables.Add("input", FormatInput(input)); + var files = new global::System.Collections.Generic.Dictionary(); + MapFilesFromArgumentInput("variables.input", input, files); + return CreateRequest(variables, files); + } + + private global::StrawberryShake.OperationRequest CreateRequest(global::System.Collections.Generic.IReadOnlyDictionary? variables, global::System.Collections.Generic.Dictionary files) + { + return new global::StrawberryShake.OperationRequest(id: TestQueryDocument.Instance.Hash.Value, name: "Test", document: TestQueryDocument.Instance, strategy: global::StrawberryShake.RequestStrategy.Default, files: files, variables: variables); + } + + private global::System.Object? FormatInput(global::Foo.Bar.CreateTaskInput value) + { + if (value is null) + { + throw new global::System.ArgumentNullException(nameof(value)); + } + + return _createTaskInputFormatter.Format(value); + } + + global::StrawberryShake.OperationRequest global::StrawberryShake.IOperationRequestFactory.Create(global::System.Collections.Generic.IReadOnlyDictionary? variables) + { + return CreateRequest(variables!, new global::System.Collections.Generic.Dictionary()); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.OperationServiceInterfaceGenerator + /// + /// Represents the operation service of the Test GraphQL operation + /// + /// query Test($input: CreateTaskInput!) { + /// upload(input: $input) + /// } + /// + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface ITestQuery : global::StrawberryShake.IOperationRequestFactory + { + global::Foo.Bar.ITestQuery With(global::System.Action configure); + global::Foo.Bar.ITestQuery WithRequestUri(global::System.Uri requestUri); + global::Foo.Bar.ITestQuery WithHttpClient(global::System.Net.Http.HttpClient httpClient); + global::System.Threading.Tasks.Task> ExecuteAsync(global::Foo.Bar.CreateTaskInput input, global::System.Threading.CancellationToken cancellationToken = default); + global::System.IObservable> Watch(global::Foo.Bar.CreateTaskInput input, 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.ITestQuery _test; + public FooClient(global::Foo.Bar.ITestQuery test) + { + _test = test ?? throw new global::System.ArgumentNullException(nameof(test)); + } + + public static global::System.String ClientName => "FooClient"; + public global::Foo.Bar.ITestQuery Test => _test; + } + + // 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.ITestQuery Test { get; } + } +} + +namespace Foo.Bar.State +{ + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultDataFactoryGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class TestResultFactory : global::StrawberryShake.IOperationResultDataFactory + { + private readonly global::StrawberryShake.IEntityStore _entityStore; + public TestResultFactory(global::StrawberryShake.IEntityStore entityStore) + { + _entityStore = entityStore ?? throw new global::System.ArgumentNullException(nameof(entityStore)); + } + + global::System.Type global::StrawberryShake.IOperationResultDataFactory.ResultType => typeof(global::Foo.Bar.ITestResult); + + public TestResult Create(global::StrawberryShake.IOperationResultDataInfo dataInfo, global::StrawberryShake.IEntityStoreSnapshot? snapshot = null) + { + if (snapshot is null) + { + snapshot = _entityStore.CurrentSnapshot; + } + + if (dataInfo is TestResultInfo info) + { + return new TestResult(info.Upload); + } + + throw new global::System.ArgumentException("TestResultInfo expected."); + } + + 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 TestResultInfo : global::StrawberryShake.IOperationResultDataInfo + { + private readonly global::System.Collections.Generic.IReadOnlyCollection _entityIds; + private readonly global::System.UInt64 _version; + public TestResultInfo(global::System.String? upload, global::System.Collections.Generic.IReadOnlyCollection entityIds, global::System.UInt64 version) + { + Upload = upload; + _entityIds = entityIds ?? throw new global::System.ArgumentNullException(nameof(entityIds)); + _version = version; + } + + public global::System.String? Upload { 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 TestResultInfo(Upload, _entityIds, version); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.InputTypeStateInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "0.0.0.0")] + internal interface ICreateTaskInputInfo + { + global::System.Boolean IsTitleSet { get; } + + global::System.Boolean IsUploadOneSet { get; } + + global::System.Boolean IsUploadTwoSet { get; } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.InputTypeStateInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "0.0.0.0")] + internal interface IFileUploadInfo + { + global::System.Boolean IsMetadataSet { get; } + + global::System.Boolean IsFileSet { get; } + + global::System.Boolean IsFile2Set { get; } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.JsonResultBuilderGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class TestBuilder : global::StrawberryShake.OperationResultBuilder + { + private readonly global::StrawberryShake.IEntityStore _entityStore; + private readonly global::StrawberryShake.IEntityIdSerializer _idSerializer; + private readonly global::StrawberryShake.Serialization.ILeafValueParser _stringParser; + private readonly global::StrawberryShake.Serialization.ILeafValueParser _uploadParser; + public TestBuilder(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."); + _uploadParser = serializerResolver.GetLeafValueParser("Upload") ?? throw new global::System.ArgumentException("No serializer for type `Upload` 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 !; + _entityStore.Update(session => + { + snapshot = session.CurrentSnapshot; + }); + return new TestResultInfo(Deserialize_String(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "upload")), entityIds, snapshot.Version); + } + + 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.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 + { + _ => throw new global::System.NotSupportedException()}; + } + + public global::System.String Format(global::StrawberryShake.EntityId entityId) + { + return entityId.Name switch + { + _ => throw new global::System.NotSupportedException()}; + } + } + + // 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(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); + 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.TestResultFactory>(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.TestBuilder>(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(); + } + } + } + } +} + +