public async Task Class_With_Field_Constructor_Property_Method() { // arrange var sb = new StringBuilder(); var writer = new CodeWriter(sb); // act await ClassBuilder.New() .SetName("MyClass") .AddImplements("SomeOtherType") .SetAbstract() .AddField(FieldBuilder.New() .SetName("_foo") .SetType("Bar") .SetReadOnly()) .AddProperty( PropertyBuilder.New() .SetName("Foo") .SetType("Bar") .SetBackingField("_foo")) .AddConstructor(ConstructorBuilder.New() .SetAccessModifier(AccessModifier.Protected) .AddParameter(ParameterBuilder.New() .SetName("foo") .SetType("Bar") .SetDefault()) .AddCode("_foo = foo;")) .AddMethod(MethodBuilder.New() .SetName("GetFooAsync") .SetReturnType("ValueTask<Bar>") .AddCode("return new ValueTask<Bar>(_foo);")) .BuildAsync(writer); // assert sb.ToString().MatchSnapshot(); }
protected override void Generate( CodeWriter writer, ITypeDescriptor typeDescriptor, out string fileName) { ComplexTypeDescriptor complexTypeDescriptor = typeDescriptor as ComplexTypeDescriptor ?? throw new InvalidOperationException( "A result entity mapper can only be generated for complex types"); var(classBuilder, constructorBuilder) = CreateClassBuilder(); var className = CreateResultInfoName(complexTypeDescriptor.RuntimeType.Name); fileName = className; classBuilder .AddImplements(TypeNames.IOperationResultDataInfo) .SetName(fileName); constructorBuilder .SetTypeName(complexTypeDescriptor.RuntimeType.Name) .SetAccessModifier(AccessModifier.Public); foreach (var prop in complexTypeDescriptor.Properties) { var propTypeBuilder = prop.Type.ToEntityIdBuilder(); // Add Property to class classBuilder.AddProperty( prop.Name, x => x.SetType(propTypeBuilder).SetAccessModifier(AccessModifier.Public)); // Add initialization of property to the constructor var paramName = GetParameterName(prop.Name); ParameterBuilder parameterBuilder = ParameterBuilder.New() .SetName(paramName) .SetType(propTypeBuilder); constructorBuilder.AddParameter(parameterBuilder); constructorBuilder.AddCode(prop.Name + " = " + paramName + ";"); } classBuilder.AddProperty( "EntityIds", x => x.SetType(TypeNames.IReadOnlyCollection.WithGeneric(TypeNames.EntityId)) .AsLambda("_entityIds")); classBuilder.AddProperty("Version", x => x.SetType("ulong").AsLambda("_version")); AddConstructorAssignedField( $"{TypeNames.IReadOnlyCollection}<{TypeNames.EntityId}>", "_entityIds", classBuilder, constructorBuilder); AddConstructorAssignedField( "ulong", "_version", classBuilder, constructorBuilder, true); // WithVersion classBuilder.AddMethod( "WithVersion", x => x.SetAccessModifier(AccessModifier.Public) .SetReturnType(TypeNames.IOperationResultDataInfo) .AddParameter(ParameterBuilder.New() .SetType("ulong") .SetName("version")) .AddCode(MethodCallBuilder.New() .SetPrefix("return new ") .SetMethodName(className) .AddArgumentRange( complexTypeDescriptor.Properties.Select(x => x.Name.Value)) .AddArgument("_entityIds") .AddArgument("_version"))); CodeFileBuilder .New() .SetNamespace(complexTypeDescriptor.RuntimeType.NamespaceWithoutGlobal) .AddType(classBuilder) .Build(writer); }
protected override void Generate( CodeWriter writer, DataTypeDescriptor descriptor, out string fileName) { // Setup class fileName = descriptor.RuntimeType.Name; AbstractTypeBuilder typeBuilder; ConstructorBuilder? constructorBuilder = null; var typenamePropName = "__typename"; if (descriptor.IsInterface) { typeBuilder = new InterfaceBuilder() .SetName(fileName); typeBuilder.AddProperty(PropertyBuilder.New() .SetName(typenamePropName) .SetType(TypeNames.String)); } else { var(classBuilder, constructorBuilder2) = CreateClassBuilder(); constructorBuilder2 .SetTypeName(fileName) .SetAccessModifier(AccessModifier.Public); constructorBuilder = constructorBuilder2; classBuilder.AddProperty( PropertyBuilder .New() .SetAccessModifier(AccessModifier.Public) .SetName(typenamePropName) .SetType(TypeNames.String)); var paramName = "typename"; var assignment = AssignmentBuilder .New() .SetLefthandSide(typenamePropName) .SetRighthandSide(paramName) .AssertNonNull(); constructorBuilder.AddParameter( ParameterBuilder .New() .SetType(TypeNames.String) .SetName(paramName)) .AddCode(assignment); classBuilder.SetName(fileName); typeBuilder = classBuilder; } // Add Properties to class foreach (PropertyDescriptor item in descriptor.Properties) { var itemParamName = GetParameterName(item.Name); var assignment = AssignmentBuilder .New() .SetLefthandSide(item.Name) .SetRighthandSide(itemParamName); var paramType = item.Type.IsEntityType() ? item.Type.ToEntityIdBuilder() : item.Type.ToBuilder(); constructorBuilder?.AddParameter( ParameterBuilder .New() .SetType(paramType) .SetName(itemParamName) .SetDefault("null")) .AddCode(assignment); switch (item.Type.Kind) { case TypeKind.LeafType: typeBuilder.AddProperty(item.Name) .SetType(item.Type.ToBuilder()) .SetAccessModifier(AccessModifier.Public); break; case TypeKind.DataType: typeBuilder.AddProperty(item.Name) // TODO this looks wrong. We should avoid nameoverride and delete it .SetType(item.Type.ToBuilder(item.Type.Name)) .SetAccessModifier(AccessModifier.Public); break; case TypeKind.EntityType: typeBuilder.AddProperty(item.Name) .SetType(item.Type.ToBuilder().SetName(TypeNames.EntityId)) .SetAccessModifier(AccessModifier.Public); break; default: throw new ArgumentOutOfRangeException(); } } foreach (NameString superType in descriptor.Implements) { typeBuilder.AddImplements(CreateDataTypeName(superType)); } CodeFileBuilder .New() .SetNamespace(descriptor.RuntimeType.NamespaceWithoutGlobal) .AddType(typeBuilder) .Build(writer); }
protected override void Generate( CodeWriter writer, ResultBuilderDescriptor resultBuilderDescriptor, out string fileName) { var processed = new HashSet <string>(); var resultTypeDescriptor = resultBuilderDescriptor.ResultNamedType; var(classBuilder, constructorBuilder) = CreateClassBuilder(); fileName = resultBuilderDescriptor.Name; classBuilder.SetName(fileName); constructorBuilder.SetTypeName(fileName); classBuilder.AddImplements( $"{TypeNames.IOperationResultBuilder}<{TypeNames.JsonDocument}," + $" {resultTypeDescriptor.Name}>"); AddConstructorAssignedField( TypeNames.IEntityStore, _entityStoreFieldName, classBuilder, constructorBuilder); AddConstructorAssignedField( TypeReferenceBuilder.New() .SetName(TypeNames.Func) .AddGeneric(TypeNames.JsonElement) .AddGeneric(TypeNames.EntityId), _extractIdFieldName, classBuilder, constructorBuilder); AddConstructorAssignedField( TypeReferenceBuilder.New() .SetName(TypeNames.IOperationResultDataFactory) .AddGeneric(resultTypeDescriptor.Name), _resultDataFactoryFieldName, classBuilder, constructorBuilder); constructorBuilder.AddParameter( ParameterBuilder.New() .SetName(_serializerResolverParamName) .SetType(TypeNames.ISerializerResolver)); IEnumerable <ValueParserDescriptor> neededSerializers = resultBuilderDescriptor .ValueParsers .ToLookup(x => x.RuntimeType) .Select(x => x.First()); foreach (ValueParserDescriptor valueParser in neededSerializers) { var parserFieldName = $"_{valueParser.RuntimeType.Split('.').Last().WithLowerFirstChar()}Parser"; classBuilder.AddField( FieldBuilder.New().SetName(parserFieldName).SetType( TypeReferenceBuilder.New() .SetName(TypeNames.ILeafValueParser) .AddGeneric(valueParser.SerializedType) .AddGeneric(valueParser.RuntimeType))); constructorBuilder.AddCode( AssignmentBuilder.New() .AssertNonNull(parserFieldName) .SetLefthandSide(parserFieldName) .SetRighthandSide( MethodCallBuilder.New() .SetPrefix(_serializerResolverParamName + ".") .SetDetermineStatement(false) .SetMethodName( $"GetLeafValueParser<{valueParser.SerializedType}, " + $"{valueParser.RuntimeType}>") .AddArgument($"\"{valueParser.GraphQLTypeName}\""))); } AddBuildMethod( resultTypeDescriptor, classBuilder); AddBuildDataMethod( resultTypeDescriptor, classBuilder); AddRequiredDeserializeMethods( resultBuilderDescriptor.ResultNamedType, classBuilder, processed); CodeFileBuilder.New() .SetNamespace(resultBuilderDescriptor.ResultNamedType.Namespace) .AddType(classBuilder) .Build(writer); }
protected override void Generate( CodeWriter writer, ResultBuilderDescriptor resultBuilderDescriptor, out string fileName) { var processed = new HashSet <string>(); var resultTypeDescriptor = resultBuilderDescriptor.ResultNamedType as InterfaceTypeDescriptor ?? throw new InvalidOperationException( "A result type can only be generated for complex types"); var(classBuilder, constructorBuilder) = CreateClassBuilder(); fileName = resultBuilderDescriptor.RuntimeType.Name; classBuilder.SetName(fileName); constructorBuilder.SetTypeName(fileName); classBuilder.AddImplements( $"{TypeNames.IOperationResultBuilder}<{TypeNames.JsonDocument}," + $" {resultTypeDescriptor.RuntimeType.Name}>"); AddConstructorAssignedField( TypeNames.IEntityStore, _entityStoreFieldName, classBuilder, constructorBuilder); AddConstructorAssignedField( TypeReferenceBuilder.New() .SetName(TypeNames.Func) .AddGeneric(TypeNames.JsonElement) .AddGeneric(TypeNames.EntityId), _extractIdFieldName, classBuilder, constructorBuilder); AddConstructorAssignedField( TypeReferenceBuilder.New() .SetName(TypeNames.IOperationResultDataFactory) .AddGeneric(resultTypeDescriptor.RuntimeType.Name), _resultDataFactoryFieldName, classBuilder, constructorBuilder); constructorBuilder.AddParameter( ParameterBuilder.New() .SetName(_serializerResolverParamName) .SetType(TypeNames.ISerializerResolver)); IEnumerable <ValueParserDescriptor> valueParsers = resultBuilderDescriptor .ValueParsers .GroupBy(t => t.Name) .Select(t => t.First()); foreach (ValueParserDescriptor valueParser in valueParsers) { var parserFieldName = $"{GetFieldName(valueParser.Name)}Parser"; classBuilder.AddField( FieldBuilder.New() .SetReadOnly() .SetName(parserFieldName) .SetType( TypeReferenceBuilder.New() .SetName(TypeNames.ILeafValueParser) .AddGeneric(valueParser.SerializedType.ToString()) .AddGeneric(valueParser.RuntimeType.ToString()))); constructorBuilder.AddCode( AssignmentBuilder.New() .SetAssertNonNull() .SetAssertException( TypeNames.ArgumentException + $"(\"No serializer for type `{valueParser.Name}` found.\")") .SetLefthandSide(parserFieldName) .SetRighthandSide( MethodCallBuilder.New() .SetPrefix(_serializerResolverParamName + ".") .SetDetermineStatement(false) .SetMethodName( $"GetLeafValueParser<{valueParser.SerializedType}, " + $"{valueParser.RuntimeType}>") .AddArgument($"\"{valueParser.Name}\""))); } AddBuildMethod( resultTypeDescriptor, classBuilder); AddBuildDataMethod( resultTypeDescriptor, classBuilder); AddRequiredDeserializeMethods( resultBuilderDescriptor.ResultNamedType, classBuilder, processed); CodeFileBuilder.New() .SetNamespace( resultBuilderDescriptor.ResultNamedType.RuntimeType.NamespaceWithoutGlobal) .AddType(classBuilder) .Build(writer); }
private void AddDataHandler( ClassBuilder classBuilder, ConstructorBuilder constructorBuilder, MethodBuilder method, NamedTypeDescriptor namedTypeDescriptor, HashSet <string> processed, bool isNonNullable) { method.AddParameter( ParameterBuilder.New() .SetType( $"global::{namedTypeDescriptor.Namespace}.State." + DataTypeNameFromTypeName(namedTypeDescriptor.GraphQLTypeName)) .SetName(DataParamName)); if (!isNonNullable) { method.AddCode( EnsureProperNullability( DataParamName, isNonNullable)); } var variableName = "returnValue"; method.AddCode($"{namedTypeDescriptor.Name} {variableName} = default!;"); method.AddEmptyLine(); if (namedTypeDescriptor.ImplementedBy.Any()) { var ifChain = InterfaceImplementeeIf(namedTypeDescriptor.ImplementedBy[0]); foreach (NamedTypeDescriptor interfaceImplementee in namedTypeDescriptor.ImplementedBy.Skip(1)) { var singleIf = InterfaceImplementeeIf(interfaceImplementee).SkipIndents(); ifChain.AddIfElse(singleIf); } ifChain.AddElse( CodeInlineBuilder.New() .SetText($"throw new {TypeNames.NotSupportedException}();")); method.AddCode(ifChain); } IfBuilder InterfaceImplementeeIf(NamedTypeDescriptor interfaceImplementee) { var ifCorrectType = IfBuilder.New(); if (isNonNullable) { ifCorrectType.SetCondition( $"{DataParamName}.__typename.Equals(\"" + $"{interfaceImplementee.GraphQLTypeName}\", " + $"{TypeNames.OrdinalStringComparisson})"); } else { ifCorrectType.SetCondition( $"{DataParamName}?.__typename.Equals(\"" + $"{interfaceImplementee.GraphQLTypeName}\", " + $"{TypeNames.OrdinalStringComparisson}) ?? false"); } var constructorCall = MethodCallBuilder.New() .SetPrefix($"{variableName} = new ") .SetMethodName(interfaceImplementee.Name); foreach (PropertyDescriptor prop in interfaceImplementee.Properties) { var propAccess = $"{DataParamName}.{prop.Name}"; if (prop.Type.IsEntityType()) { constructorCall.AddArgument( BuildMapMethodCall( DataParamName, prop, true)); } else { constructorCall.AddArgument( $"{propAccess} ?? throw new {TypeNames.ArgumentNullException}()"); } } ifCorrectType.AddCode(constructorCall); return(ifCorrectType); } method.AddCode($"return {variableName};"); AddRequiredMapMethods( DataParamName, namedTypeDescriptor, classBuilder, constructorBuilder, processed); }
public MethodBuilder AddParameter(ParameterBuilder value) { _parameters.Add(value); return(this); }
protected override Task WriteAsync( CodeWriter writer, EnumValueSerializerDescriptor descriptor) { if (writer is null) { throw new ArgumentNullException(nameof(writer)); } if (descriptor is null) { throw new ArgumentNullException(nameof(descriptor)); } return(ClassBuilder.New() .SetAccessModifier(AccessModifier.Public) .SetSealed() .SetName(descriptor.Name) .AddImplements("global::StrawberryShake.IValueSerializer") .AddProperty(PropertyBuilder.New() .SetAccessModifier(AccessModifier.Public) .SetType("string") .SetName("Name") .SetGetter(CodeLineBuilder.New() .SetLine($"return \"{descriptor.EnumGraphQLTypeName}\";"))) .AddProperty(PropertyBuilder.New() .SetAccessModifier(AccessModifier.Public) .SetType("global::StrawberryShake.ValueKind") .SetName("Kind") .SetGetter(CodeLineBuilder.New() .SetLine($"return global::StrawberryShake.ValueKind.Enum;"))) .AddProperty(PropertyBuilder.New() .SetAccessModifier(AccessModifier.Public) .SetType("global::System.Type") .SetName("ClrType") .SetGetter(CodeLineBuilder.New() .SetLine($"return typeof({descriptor.EnumTypeName});"))) .AddProperty(PropertyBuilder.New() .SetAccessModifier(AccessModifier.Public) .SetType("global::System.Type") .SetName("SerializationType") .SetGetter(CodeLineBuilder.New() .SetLine($"return typeof(string);"))) .AddMethod(MethodBuilder.New() .SetAccessModifier(AccessModifier.Public) .SetReturnType("object?", NullableRefTypes) .SetReturnType("object", !NullableRefTypes) .SetName("Serialize") .AddParameter(ParameterBuilder.New() .SetType("object?", NullableRefTypes) .SetType("object", !NullableRefTypes) .SetName("value")) .AddCode(CreateSerializerMethodBody(descriptor, CodeWriter.Indent))) .AddMethod(MethodBuilder.New() .SetAccessModifier(AccessModifier.Public) .SetReturnType("object?", NullableRefTypes) .SetReturnType("object", !NullableRefTypes) .SetName("Deserialize") .AddParameter(ParameterBuilder.New() .SetType("object?", NullableRefTypes) .SetType("object", !NullableRefTypes) .SetName("serialized")) .AddCode(CreateDeserializerMethodBody(descriptor, CodeWriter.Indent))) .BuildAsync(writer)); }
protected override void Generate( CodeWriter writer, ITypeDescriptor typeDescriptor, out string fileName) { var(classBuilder, constructorBuilder) = CreateClassBuilder(false); ComplexTypeDescriptor descriptor = typeDescriptor as ComplexTypeDescriptor ?? throw new InvalidOperationException( "A result entity mapper can only be generated for complex types"); // Setup class fileName = descriptor.ExtractMapperName(); classBuilder .AddImplements( TypeNames.IEntityMapper .WithGeneric(descriptor.ExtractTypeName(), descriptor.RuntimeType.Name)) .SetName(fileName); constructorBuilder.SetTypeName(descriptor.Name); if (descriptor.ContainsEntity()) { AddConstructorAssignedField( TypeNames.IEntityStore, StoreFieldName, classBuilder, constructorBuilder); } // Define map method MethodBuilder mapMethod = MethodBuilder.New() .SetName(_mapMethodName) .SetAccessModifier(AccessModifier.Public) .SetReturnType(descriptor.RuntimeType.Name) .AddParameter( ParameterBuilder.New() .SetType( descriptor.Kind == TypeKind.EntityType ? CreateEntityTypeName(descriptor.Name) : descriptor.Name) .SetName(_entityParamName)); var constructorCall = MethodCallBuilder .New() .SetMethodName($"return new {descriptor.RuntimeType.Name}"); if (typeDescriptor is ComplexTypeDescriptor complexTypeDescriptor) { foreach (PropertyDescriptor property in complexTypeDescriptor.Properties) { constructorCall.AddArgument(BuildMapMethodCall(_entityParamName, property)); } } mapMethod.AddCode(constructorCall); if (constructorBuilder.HasParameters()) { classBuilder.AddConstructor(constructorBuilder); } classBuilder.AddMethod(mapMethod); AddRequiredMapMethods( _entityParamName, descriptor, classBuilder, constructorBuilder, new HashSet <string>()); CodeFileBuilder .New() .SetNamespace(descriptor.RuntimeType.NamespaceWithoutGlobal) .AddType(classBuilder) .Build(writer); }
private void AddEntityHandler( ClassBuilder classBuilder, ConstructorBuilder constructorBuilder, MethodBuilder method, NamedTypeDescriptor namedTypeDescriptor, HashSet <string> processed, bool isNonNullable) { var nullabilityAdditive = "?"; if (isNonNullable) { nullabilityAdditive = ""; } method.AddParameter( ParameterBuilder.New() .SetType(TypeNames.EntityId + nullabilityAdditive) .SetName(EntityIdParamName)); if (!isNonNullable) { method.AddCode( EnsureProperNullability( EntityIdParamName, isNonNullable)); } foreach (NamedTypeDescriptor implementee in namedTypeDescriptor.ImplementedBy) { var dataMapperName = EntityMapperNameFromGraphQLTypeName( implementee.Name, implementee.GraphQLTypeName); if (processed.Add(dataMapperName)) { var dataMapperType = $"{TypeNames.IEntityMapper}<" + $"{EntityTypeNameFromGraphQLTypeName(implementee.GraphQLTypeName)}, " + $"{implementee.Name}>"; AddConstructorAssignedField( dataMapperType, dataMapperName.ToFieldName(), classBuilder, constructorBuilder); } } foreach (NamedTypeDescriptor interfaceImplementee in namedTypeDescriptor.ImplementedBy) { method.AddCode(InterfaceImplementeeIf(interfaceImplementee)); } method.AddCode(ExceptionBuilder.New(TypeNames.NotSupportedException)); IfBuilder InterfaceImplementeeIf(NamedTypeDescriptor interfaceImplementee) { var dataMapperName = EntityMapperNameFromGraphQLTypeName( interfaceImplementee.Name, interfaceImplementee.GraphQLTypeName) .ToFieldName(); var ifCorrectType = IfBuilder.New(); if (isNonNullable) { ifCorrectType.SetCondition( $"{EntityIdParamName}.Name.Equals(\"" + $"{interfaceImplementee.GraphQLTypeName}\", " + $"{TypeNames.OrdinalStringComparisson})"); } else { ifCorrectType.SetCondition( $"{EntityIdParamName}.Value.Name.Equals(\"" + $"{interfaceImplementee.GraphQLTypeName}\", " + $"{TypeNames.OrdinalStringComparisson})"); } MethodCallBuilder constructorCall = MethodCallBuilder.New() .SetPrefix($"return {dataMapperName}.") .SetWrapArguments() .SetMethodName(nameof(IEntityMapper <object, object> .Map)); MethodCallBuilder argument = MethodCallBuilder.New() .SetMethodName($"{StoreFieldName}.{nameof(IEntityStore.GetEntity)}") .SetDetermineStatement(false) .AddGeneric( EntityTypeNameFromGraphQLTypeName(interfaceImplementee.GraphQLTypeName)) .AddArgument(isNonNullable ? EntityIdParamName : $"{EntityIdParamName}.Value"); constructorCall.AddArgument( NullCheckBuilder.New() .SetDetermineStatement(false) .SetCondition(argument) .SetCode(ExceptionBuilder .New(TypeNames.GraphQLClientException) .SetDetermineStatement(false))); method.AddEmptyLine(); ifCorrectType.AddCode(constructorCall); return(ifCorrectType); } }
public ConstructorBuilder AddParameter(ParameterBuilder value) { _parameters.Add(value); return(this); }
protected override void Generate( CodeWriter writer, ITypeDescriptor typeDescriptor, out string fileName) { var(classBuilder, constructorBuilder) = CreateClassBuilder(false); NamedTypeDescriptor descriptor = (NamedTypeDescriptor)typeDescriptor.NamedType(); // Setup class fileName = descriptor.ExtractMapperName(); classBuilder .AddImplements( TypeNames.IEntityMapper .WithGeneric(descriptor.ExtractTypeName(), descriptor.Name)) .SetName(fileName); constructorBuilder.SetTypeName(descriptor.Name); if (descriptor.ContainsEntity()) { AddConstructorAssignedField( TypeNames.IEntityStore, StoreFieldName, classBuilder, constructorBuilder); } // Define map method MethodBuilder mapMethod = MethodBuilder.New() .SetName(_mapMethodName) .SetAccessModifier(AccessModifier.Public) .SetReturnType(descriptor.Name) .AddParameter( ParameterBuilder.New() .SetType( descriptor.Kind == TypeKind.EntityType ? EntityTypeNameFromGraphQLTypeName(descriptor.GraphQLTypeName) : descriptor.Name) .SetName(_entityParamName)); var constructorCall = MethodCallBuilder .New() .SetMethodName($"return new {descriptor.Name}"); if (typeDescriptor is NamedTypeDescriptor namedTypeDescriptor) { foreach (PropertyDescriptor property in namedTypeDescriptor.Properties) { constructorCall.AddArgument(BuildMapMethodCall(_entityParamName, property)); } } mapMethod.AddCode(constructorCall); if (constructorBuilder.HasParameters()) { classBuilder.AddConstructor(constructorBuilder); } classBuilder.AddMethod(mapMethod); var processed = new HashSet <string>(); AddRequiredMapMethods( _entityParamName, descriptor, classBuilder, constructorBuilder, processed); CodeFileBuilder .New() .SetNamespace(descriptor.Namespace) .AddType(classBuilder) .Build(writer); }
private void AddBuildDataMethod( NamedTypeDescriptor resultNamedType, ClassBuilder classBuilder) { var objParameter = "obj"; var buildDataMethod = MethodBuilder.New() .SetAccessModifier(AccessModifier.Private) .SetName("BuildData") .SetReturnType( $"({resultNamedType.Name}, " + $"{ResultInfoNameFromTypeName(resultNamedType.ImplementedBy[0].Name)})") .AddParameter( ParameterBuilder.New() .SetType(TypeNames.JsonElement) .SetName(objParameter)); var sessionName = "session"; buildDataMethod.AddCode( CodeLineBuilder.New() .SetLine( CodeBlockBuilder.New() .AddCode( $"using {TypeNames.IEntityUpdateSession} {sessionName} = ") .AddCode(_entityStoreFieldName + ".BeginUpdate();"))); var entityIdsName = "entityIds"; buildDataMethod.AddCode( CodeLineBuilder.New() .SetLine( $"var {entityIdsName} = new {TypeNames.HashSet}<{TypeNames.EntityId}>();")); buildDataMethod.AddEmptyLine(); foreach (PropertyDescriptor property in resultNamedType.Properties.Where(prop => prop.Type.IsEntityType())) { buildDataMethod.AddCode( AssignmentBuilder.New() .SetLefthandSide(CodeBlockBuilder.New() .AddCode(property.Type.ToEntityIdBuilder()) .AddCode($"{property.Name.WithLowerFirstChar()}Id")) .SetRighthandSide(BuildUpdateMethodCall(property, ""))); } var resultInfoConstructor = MethodCallBuilder.New() .SetMethodName( $"new {ResultInfoNameFromTypeName(resultNamedType.ImplementedBy[0].Name)}") .SetDetermineStatement(false); foreach (PropertyDescriptor property in resultNamedType.Properties) { if (property.Type.IsEntityType()) { resultInfoConstructor.AddArgument($"{property.Name.WithLowerFirstChar()}Id"); } else { resultInfoConstructor.AddArgument(BuildUpdateMethodCall(property, "")); } } resultInfoConstructor.AddArgument(entityIdsName); resultInfoConstructor.AddArgument( $"{sessionName}.{TypeNames.IEntityUpdateSession_Version}"); buildDataMethod.AddEmptyLine(); var resultInfoName = "resultInfo"; buildDataMethod.AddCode( AssignmentBuilder.New() .SetLefthandSide($"var {resultInfoName}") .SetRighthandSide(resultInfoConstructor)); buildDataMethod.AddEmptyLine(); buildDataMethod.AddCode( $"return ({_resultDataFactoryFieldName}" + $".Create({resultInfoName}), {resultInfoName});"); classBuilder.AddMethod(buildDataMethod); }