public static TypeReferenceBuilder ToTypeReference( this ITypeDescriptor typeReferenceDescriptor, TypeReferenceBuilder?builder = null) { TypeReferenceBuilder actualBuilder = builder ?? TypeReferenceBuilder.New(); if (typeReferenceDescriptor is NonNullTypeDescriptor n) { typeReferenceDescriptor = n.InnerType; } else { actualBuilder.SetIsNullable(true); } return(typeReferenceDescriptor switch { ListTypeDescriptor list => ToTypeReference(list.InnerType, actualBuilder.SetListType()), EnumTypeDescriptor @enum => actualBuilder.SetName(@enum.RuntimeType.ToString()), ILeafTypeDescriptor leaf => actualBuilder.SetName(leaf.RuntimeType.ToString()), INamedTypeDescriptor named => actualBuilder.SetName(named.RuntimeType.ToString()), _ => throw new ArgumentOutOfRangeException(nameof(typeReferenceDescriptor)) });
public static void Map(ClientModel model, IMapperContext context) { foreach (OperationModel modelOperation in model.Operations) { var arguments = modelOperation.Arguments.Select( arg => { NameString typeName = arg.Type.TypeName(); INamedTypeDescriptor namedTypeDescriptor = context.Types.Single(type => type.Name.Equals(typeName)); return(new PropertyDescriptor( arg.Name, Rewrite(arg.Type, namedTypeDescriptor))); }) .ToList(); var resultTypeName = CreateResultRootTypeName(modelOperation.ResultType.Name); switch (modelOperation.OperationType) { case OperationType.Query: context.Register( modelOperation.Name, new QueryOperationDescriptor( modelOperation.Name, context.Types.Single(t => t.RuntimeType.Name.Equals(resultTypeName)), context.Namespace, arguments, modelOperation.Document.ToString())); break; case OperationType.Mutation: context.Register( modelOperation.Name, new MutationOperationDescriptor( modelOperation.Name, context.Types.Single(t => t.RuntimeType.Name.Equals(resultTypeName)), context.Namespace, arguments, modelOperation.Document.ToString())); break; case OperationType.Subscription: context.Register( modelOperation.Name, new SubscriptionOperationDescriptor( modelOperation.Name, context.Types.Single(t => t.RuntimeType.Name.Equals(resultTypeName)), context.Namespace, arguments, modelOperation.Document.ToString())); break; default: throw new ArgumentOutOfRangeException(); } } }
public ResultFromEntityTypeMapperDescriptor( INamedTypeDescriptor entityNamedType, INamedTypeDescriptor resultNamedType) { EntityNamedType = entityNamedType; ResultNamedType = resultNamedType; }
public static RuntimeTypeInfo ExtractType( this INamedTypeDescriptor descriptor) { return(descriptor.IsEntityType() ? CreateEntityType(descriptor.Name, descriptor.RuntimeType.NamespaceWithoutGlobal) : new (descriptor.Name, descriptor.RuntimeType.NamespaceWithoutGlobal)); }
/// <summary> /// Adds all required deserializers of the given type descriptors properties /// </summary> private void AddRequiredDeserializeMethods( INamedTypeDescriptor namedTypeDescriptor, ClassBuilder classBuilder, HashSet <string> processed) { if (namedTypeDescriptor is InterfaceTypeDescriptor interfaceTypeDescriptor) { foreach (var @class in interfaceTypeDescriptor.ImplementedBy) { AddRequiredDeserializeMethods(@class, classBuilder, processed); } } else if (namedTypeDescriptor is ComplexTypeDescriptor complexTypeDescriptor) { foreach (var property in complexTypeDescriptor.Properties) { AddDeserializeMethod( property.Type, classBuilder, processed); if (property.Type.NamedType() is INamedTypeDescriptor nt && !nt.IsLeafType()) { AddRequiredDeserializeMethods(nt, classBuilder, processed); } } } }
public ResultBuilderDescriptor( RuntimeTypeInfo runtimeType, INamedTypeDescriptor resultNamedType, IReadOnlyCollection <ValueParserDescriptor> valueParsers) { ResultNamedType = resultNamedType; RuntimeType = runtimeType; ValueParsers = valueParsers; }
public static NameString ExtractMapperName(this INamedTypeDescriptor descriptor) { return(descriptor.Kind == TypeKind.EntityType ? CreateEntityMapperName( descriptor.RuntimeType.Name, descriptor.Name) : CreateDataMapperName( descriptor.RuntimeType.Name, descriptor.Name)); }
public ResultBuilderDescriptor( string name, INamedTypeDescriptor resultNamedType, IReadOnlyCollection <ValueParserDescriptor> valueParsers) { _name = name; ResultNamedType = resultNamedType; RuntimeType = new(NamingConventions.CreateResultBuilderName(_name)); ValueParsers = valueParsers; }
private void AddUpdateEntityMethod( ClassBuilder classBuilder, MethodBuilder methodBuilder, INamedTypeDescriptor namedTypeDescriptor, HashSet <string> processed) { methodBuilder.AddCode( AssignmentBuilder .New() .SetLefthandSide($"{TypeNames.EntityId} {_entityId}") .SetRighthandSide( MethodCallBuilder .Inline() .SetMethodName(_idSerializer, "Parse") .AddArgument($"{_obj}.Value"))); methodBuilder.AddCode( MethodCallBuilder .New() .SetMethodName(_entityIds, nameof(List <object> .Add)) .AddArgument(_entityId)); methodBuilder.AddEmptyLine(); if (namedTypeDescriptor is InterfaceTypeDescriptor interfaceTypeDescriptor) { // If the type is an interface foreach (ObjectTypeDescriptor concreteType in interfaceTypeDescriptor.ImplementedBy) { methodBuilder .AddEmptyLine() .AddCode(CreateUpdateEntityStatement(concreteType) .AddCode($"return {_entityId};")); } methodBuilder.AddEmptyLine(); methodBuilder.AddCode(ExceptionBuilder.New(TypeNames.NotSupportedException)); } else if (namedTypeDescriptor is ObjectTypeDescriptor objectTypeDescriptor) { BuildTryGetEntityIf( CreateEntityType( objectTypeDescriptor.Name, objectTypeDescriptor.RuntimeType.NamespaceWithoutGlobal)) .AddCode(CreateEntityConstructorCall(objectTypeDescriptor, false)) .AddElse(CreateEntityConstructorCall(objectTypeDescriptor, true)); methodBuilder.AddEmptyLine(); methodBuilder.AddCode($"return {_entityId};"); } AddRequiredDeserializeMethods(namedTypeDescriptor, classBuilder, processed); }
private static ITypeDescriptor Rewrite( IType type, INamedTypeDescriptor namedTypeDescriptor) { switch (type) { case NonNullType nnt: return(new NonNullTypeDescriptor(Rewrite(nnt.InnerType(), namedTypeDescriptor))); case ListType lt: return(new ListTypeDescriptor(Rewrite(lt.InnerType(), namedTypeDescriptor))); case INamedType: return(namedTypeDescriptor); default: throw new InvalidOperationException(); } }
private void AddUpdateEntityMethod( ClassBuilder classBuilder, MethodBuilder methodBuilder, INamedTypeDescriptor namedTypeDescriptor, HashSet <string> processed) { methodBuilder.AddCode( AssignmentBuilder .New() .SetLefthandSide($"{TypeNames.EntityId} {_entityId}") .SetRighthandSide( MethodCallBuilder .Inline() .SetMethodName(_extractId) .AddArgument($"{_obj}.{nameof(Nullable<EntityId>.Value)}"))); methodBuilder.AddCode( MethodCallBuilder .New() .SetMethodName(_entityIds, nameof(List <object> .Add)) .AddArgument(_entityId)); methodBuilder.AddEmptyLine(); if (namedTypeDescriptor is InterfaceTypeDescriptor interfaceTypeDescriptor) { // If the type is an interface foreach (ObjectTypeDescriptor concreteType in interfaceTypeDescriptor.ImplementedBy) { IfBuilder ifStatement = IfBuilder .New() .SetCondition( MethodCallBuilder .Inline() .SetMethodName( _entityId, nameof(EntityId.Name), nameof(string.Equals)) .AddArgument(concreteType.Name.AsStringToken()) .AddArgument(TypeNames.OrdinalStringComparison)); var entityTypeName = CreateEntityTypeName(concreteType.Name); WriteEntityLoader( ifStatement, entityTypeName); WritePropertyAssignments( ifStatement, concreteType.Properties); ifStatement .AddEmptyLine() .AddCode($"return {_entityId};"); methodBuilder .AddEmptyLine() .AddCode(ifStatement); } methodBuilder.AddEmptyLine(); methodBuilder.AddCode(ExceptionBuilder.New(TypeNames.NotSupportedException)); } else if (namedTypeDescriptor is ComplexTypeDescriptor complexTypeDescriptor) { WriteEntityLoader(methodBuilder, CreateEntityTypeName(namedTypeDescriptor.Name)); WritePropertyAssignments(methodBuilder, complexTypeDescriptor.Properties); methodBuilder.AddEmptyLine(); methodBuilder.AddCode($"return {_entityId};"); } AddRequiredDeserializeMethods(namedTypeDescriptor, classBuilder, processed); }
private void AddUpdateEntityMethod( ClassBuilder classBuilder, MethodBuilder methodBuilder, INamedTypeDescriptor namedTypeDescriptor, HashSet <string> processed) { var entityIdVarName = "entityId"; methodBuilder.AddCode( AssignmentBuilder.New() .SetLefthandSide( CodeBlockBuilder.New() .AddCode(TypeNames.EntityId) .AddCode($" {entityIdVarName}")) .SetRighthandSide($"{_extractIdFieldName}({_objParamName}.Value)")); methodBuilder.AddCode($"{_entityIdsParam}.Add({entityIdVarName});"); methodBuilder.AddEmptyLine(); var entityVarName = "entity"; if (namedTypeDescriptor is InterfaceTypeDescriptor interfaceTypeDescriptor) { // If the type is an interface foreach (ObjectTypeDescriptor concreteType in interfaceTypeDescriptor.ImplementedBy) { methodBuilder.AddEmptyLine(); var ifStatement = IfBuilder.New() .SetCondition( $"entityId.Name.Equals(\"{concreteType.Name}\", " + $"{TypeNames.OrdinalStringComparison})"); var entityTypeName = CreateEntityTypeName(concreteType.Name); WriteEntityLoader( ifStatement, entityTypeName, entityVarName, entityIdVarName); WritePropertyAssignments( ifStatement, concreteType.Properties, entityVarName); ifStatement.AddEmptyLine(); ifStatement.AddCode($"return {entityIdVarName};"); methodBuilder.AddCode(ifStatement); } methodBuilder.AddEmptyLine(); methodBuilder.AddCode($"throw new {TypeNames.NotSupportedException}();"); } else if (namedTypeDescriptor is ComplexTypeDescriptor complexTypeDescriptor) { WriteEntityLoader( methodBuilder, CreateEntityTypeName(namedTypeDescriptor.Name), entityVarName, entityIdVarName); WritePropertyAssignments( methodBuilder, complexTypeDescriptor.Properties, entityVarName); methodBuilder.AddEmptyLine(); methodBuilder.AddCode($"return {entityIdVarName};"); } AddRequiredDeserializeMethods( namedTypeDescriptor, classBuilder, processed); }
private ICode GenerateInternalMethodBody(DependencyInjectionDescriptor descriptor) { bool hasSubscriptions = descriptor.Operations.OfType <SubscriptionOperationDescriptor>().Any(); bool hasQueries = descriptor.Operations.OfType <QueryOperationDescriptor>().Any(); bool hasMutations = descriptor.Operations.OfType <MutationOperationDescriptor>().Any(); var body = CodeBlockBuilder .New() .AddCode(_staticCode); if (hasSubscriptions) { body.AddCode(RegisterWebSocketConnection(descriptor.Name)); } if (hasQueries || hasMutations) { body.AddCode(RegisterHttpConnection(descriptor.Name)); } body.AddEmptyLine(); foreach (var typeDescriptor in descriptor.TypeDescriptors .OfType <INamedTypeDescriptor>()) { if (typeDescriptor.Kind == TypeKind.EntityType && !typeDescriptor.IsInterface()) { INamedTypeDescriptor namedTypeDescriptor = (INamedTypeDescriptor)typeDescriptor.NamedType(); NameString className = namedTypeDescriptor.ExtractMapperName(); var interfaceName = TypeNames.IEntityMapper.WithGeneric( namedTypeDescriptor.ExtractTypeName(), typeDescriptor.RuntimeType.Name); body.AddMethodCall() .SetMethodName(TypeNames.AddSingleton) .AddGeneric(interfaceName) .AddGeneric(className) .AddArgument(_services); } } body.AddEmptyLine(); foreach (var enumType in descriptor.EnumTypeDescriptor) { body.AddMethodCall() .SetMethodName(TypeNames.AddSingleton) .AddGeneric(TypeNames.ISerializer) .AddGeneric(CreateEnumParserName(enumType.Name)) .AddArgument(_services); } foreach (var serializer in _serializers) { body.AddMethodCall() .SetMethodName(TypeNames.AddSingleton) .AddGeneric(TypeNames.ISerializer) .AddGeneric(serializer) .AddArgument(_services); } RuntimeTypeInfo stringTypeInfo = TypeInfos.From(TypeNames.String); foreach (var scalar in descriptor.TypeDescriptors.OfType <ScalarTypeDescriptor>()) { if (scalar.RuntimeType.Equals(stringTypeInfo) && scalar.SerializationType.Equals(stringTypeInfo) && !BuiltInScalarNames.IsBuiltInScalar(scalar.Name)) { body.AddMethodCall() .SetMethodName(TypeNames.AddSingleton) .AddGeneric(TypeNames.ISerializer) .AddArgument(_services) .AddArgument(MethodCallBuilder .Inline() .SetNew() .SetMethodName(TypeNames.StringSerializer) .AddArgument(scalar.Name.AsStringToken())); } } foreach (var inputTypeDescriptor in descriptor.TypeDescriptors .Where(x => x.Kind is TypeKind.InputType)) { body.AddMethodCall() .SetMethodName(TypeNames.AddSingleton) .AddGeneric(TypeNames.ISerializer) .AddGeneric(CreateInputValueFormatter( (InputObjectTypeDescriptor)inputTypeDescriptor.NamedType())) .AddArgument(_services); } body.AddCode(RegisterSerializerResolver()); body.AddEmptyLine(); foreach (var operation in descriptor.Operations) { if (!(operation.ResultTypeReference is InterfaceTypeDescriptor typeDescriptor)) { continue; } string connectionKind = operation is SubscriptionOperationDescriptor ? TypeNames.WebSocketConnection : TypeNames.HttpConnection; NameString operationName = operation.OperationName; NameString fullName = operation.Name; NameString operationInterface = typeDescriptor.RuntimeType.Name; // The factories are generated based on the concrete result type, which is the // only implementee of the result type interface. var factoryName = CreateResultFactoryName( typeDescriptor.ImplementedBy.First().RuntimeType.Name); var builderName = CreateResultBuilderName(operationName); body.AddCode( RegisterOperation( connectionKind, fullName, operationInterface, factoryName, builderName)); } body.AddCode( MethodCallBuilder .New() .SetMethodName(TypeNames.AddSingleton) .AddGeneric(descriptor.RuntimeType.Name) .AddArgument(_services)); body.AddLine($"return {_services};"); return(body); }
public static NameString ExtractTypeName(this INamedTypeDescriptor descriptor) { return(descriptor.IsEntityType() ? CreateEntityTypeName(descriptor.Name) : descriptor.Name); }
public static void Map(ClientModel model, IMapperContext context) { foreach (OperationModel modelOperation in model.Operations) { var arguments = modelOperation.Arguments.Select( arg => { NameString typeName = arg.Type.TypeName(); INamedTypeDescriptor namedTypeDescriptor = context.Types.Single(type => type.Name.Equals(typeName)); return(new PropertyDescriptor( arg.Name, arg.Variable.Variable.Name.Value, Rewrite(arg.Type, namedTypeDescriptor), null)); }) .ToList(); RuntimeTypeInfo resultType = context.GetRuntimeType( modelOperation.ResultType.Name, Descriptors.TypeDescriptors.TypeKind.ResultType); string bodyString = modelOperation.Document.ToString(); byte[] body = Encoding.UTF8.GetBytes(modelOperation.Document.ToString(false)); string hash = context.HashProvider.ComputeHash(body); switch (modelOperation.OperationType) { case OperationType.Query: context.Register( modelOperation.Name, new QueryOperationDescriptor( modelOperation.Name, context.Namespace, context.Types.Single(t => t.RuntimeType.Equals(resultType)), arguments, body, bodyString, context.HashProvider.Name, hash, context.RequestStrategy)); break; case OperationType.Mutation: context.Register( modelOperation.Name, new MutationOperationDescriptor( modelOperation.Name, context.Namespace, context.Types.Single(t => t.RuntimeType.Equals(resultType)), arguments, body, bodyString, context.HashProvider.Name, hash, context.RequestStrategy)); break; case OperationType.Subscription: context.Register( modelOperation.Name, new SubscriptionOperationDescriptor( modelOperation.Name, context.Namespace, context.Types.Single(t => t.RuntimeType.Equals(resultType)), arguments, body, bodyString, context.HashProvider.Name, hash, context.RequestStrategy)); break; default: throw new ArgumentOutOfRangeException(); } } }
private static ICode GenerateInternalMethodBody( CSharpSyntaxGeneratorSettings settings, DependencyInjectionDescriptor descriptor, TransportProfile profile) { var rootNamespace = descriptor.ClientDescriptor.RuntimeType.Namespace; var hasSubscriptions = descriptor.Operations.OfType <SubscriptionOperationDescriptor>().Any(); var hasQueries = descriptor.Operations.OfType <QueryOperationDescriptor>().Any(); var hasMutations = descriptor.Operations.OfType <MutationOperationDescriptor>().Any(); CodeBlockBuilder body = CodeBlockBuilder .New() .AddCode(CreateBaseCode(settings)); var generatedConnections = new HashSet <TransportType>(); if (hasSubscriptions) { generatedConnections.Add(profile.Subscription); body.AddCode( RegisterConnection(profile.Subscription, descriptor.Name)); } if (hasQueries && !generatedConnections.Contains(profile.Query)) { generatedConnections.Add(profile.Query); body.AddCode(RegisterConnection(profile.Query, descriptor.Name)); } if (hasMutations && !generatedConnections.Contains(profile.Mutation)) { generatedConnections.Add(profile.Mutation); body.AddCode(RegisterConnection(profile.Mutation, descriptor.Name)); } body.AddEmptyLine(); foreach (var typeDescriptor in descriptor.TypeDescriptors .OfType <INamedTypeDescriptor>()) { if (typeDescriptor.Kind == TypeKind.Entity && !typeDescriptor.IsInterface()) { INamedTypeDescriptor namedTypeDescriptor = (INamedTypeDescriptor)typeDescriptor.NamedType(); NameString className = namedTypeDescriptor.ExtractMapperName(); var interfaceName = TypeNames.IEntityMapper.WithGeneric( namedTypeDescriptor.ExtractType().ToString(), $"{rootNamespace}.{typeDescriptor.RuntimeType.Name}"); body.AddMethodCall() .SetMethodName(TypeNames.AddSingleton) .AddGeneric(interfaceName) .AddGeneric($"{CreateStateNamespace(rootNamespace)}.{className}") .AddArgument(_services); } } body.AddEmptyLine(); foreach (var enumType in descriptor.EnumTypeDescriptor) { body.AddMethodCall() .SetMethodName(TypeNames.AddSingleton) .AddGeneric(TypeNames.ISerializer) .AddGeneric(CreateEnumParserName($"{rootNamespace}.{enumType.Name}")) .AddArgument(_services); } foreach (var serializer in _serializers) { body.AddMethodCall() .SetMethodName(TypeNames.AddSingleton) .AddGeneric(TypeNames.ISerializer) .AddGeneric(serializer) .AddArgument(_services); } RuntimeTypeInfo stringTypeInfo = new RuntimeTypeInfo(TypeNames.String); foreach (var scalar in descriptor.TypeDescriptors.OfType <ScalarTypeDescriptor>()) { if (scalar.RuntimeType.Equals(stringTypeInfo) && scalar.SerializationType.Equals(stringTypeInfo) && !BuiltInScalarNames.IsBuiltInScalar(scalar.Name)) { body.AddMethodCall() .SetMethodName(TypeNames.AddSingleton) .AddGeneric(TypeNames.ISerializer) .AddArgument(_services) .AddArgument(MethodCallBuilder .Inline() .SetNew() .SetMethodName(TypeNames.StringSerializer) .AddArgument(scalar.Name.AsStringToken())); } } foreach (var inputTypeDescriptor in descriptor.TypeDescriptors .Where(x => x.Kind is TypeKind.Input)) { var formatter = CreateInputValueFormatter( (InputObjectTypeDescriptor)inputTypeDescriptor.NamedType()); body.AddMethodCall() .SetMethodName(TypeNames.AddSingleton) .AddGeneric(TypeNames.ISerializer) .AddGeneric($"{rootNamespace}.{formatter}") .AddArgument(_services); } body.AddCode(RegisterSerializerResolver()); body.AddEmptyLine(); foreach (var operation in descriptor.Operations) { if (!(operation.ResultTypeReference is InterfaceTypeDescriptor typeDescriptor)) { continue; } TransportType operationKind = operation switch { SubscriptionOperationDescriptor => profile.Subscription, QueryOperationDescriptor => profile.Query, MutationOperationDescriptor => profile.Mutation, _ => throw ThrowHelper.DependencyInjection_InvalidOperationKind(operation) }; string connectionKind = operationKind switch { TransportType.Http => TypeNames.IHttpConnection, TransportType.WebSocket => TypeNames.IWebSocketConnection, TransportType.InMemory => TypeNames.IInMemoryConnection, { } v => throw ThrowHelper.DependencyInjection_InvalidTransportType(v) }; string operationName = operation.Name; string fullName = operation.RuntimeType.ToString(); string operationInterfaceName = operation.InterfaceType.ToString(); string resultInterface = typeDescriptor.RuntimeType.ToString(); // The factories are generated based on the concrete result type, which is the // only implementee of the result type interface. var factoryName = CreateResultFactoryName( typeDescriptor.ImplementedBy.First().RuntimeType.Name); var builderName = CreateResultBuilderName(operationName); body.AddCode( RegisterOperation( settings, connectionKind, fullName, operationInterfaceName, resultInterface, $"{CreateStateNamespace(operation.RuntimeType.Namespace)}.{factoryName}", $"{CreateStateNamespace(operation.RuntimeType.Namespace)}.{builderName}")); } if (settings.IsStoreEnabled()) { body.AddCode( MethodCallBuilder .New() .SetMethodName(TypeNames.AddSingleton) .AddGeneric(TypeNames.IEntityIdSerializer) .AddGeneric(descriptor.EntityIdFactoryDescriptor.Type.ToString()) .AddArgument(_services)); } body.AddCode( MethodCallBuilder .New() .SetMethodName(TypeNames.AddSingleton) .AddGeneric(descriptor.ClientDescriptor.RuntimeType.ToString()) .AddArgument(_services)); body.AddCode( MethodCallBuilder .New() .SetMethodName(TypeNames.AddSingleton) .AddGeneric(descriptor.ClientDescriptor.InterfaceType.ToString()) .AddArgument(_services) .AddArgument(LambdaBuilder .New() .AddArgument(_sp) .SetCode(MethodCallBuilder .Inline() .SetMethodName(TypeNames.GetRequiredService) .AddGeneric(descriptor.ClientDescriptor.RuntimeType.ToString()) .AddArgument(_sp)))); body.AddLine($"return {_services};"); return(body); }
private ICode GenerateInternalMethodBody(DependencyInjectionDescriptor descriptor) { bool hasSubscriptions = descriptor.Operations.OfType <SubscriptionOperationDescriptor>().Any(); bool hasQueries = descriptor.Operations.OfType <QueryOperationDescriptor>().Any(); bool hasMutations = descriptor.Operations.OfType <MutationOperationDescriptor>().Any(); var stringBuilder = new StringBuilder(); var codeWriter = new CodeWriter(stringBuilder); stringBuilder.AppendLine(_staticCode); codeWriter.WriteComment("register connections"); if (hasSubscriptions) { stringBuilder.AppendLine(RegisterWebSocketConnection(descriptor.Name)); } if (hasQueries || hasMutations) { stringBuilder.AppendLine(RegisterHttpConnection(descriptor.Name)); } codeWriter.WriteComment("register mappers"); codeWriter.WriteLine(); foreach (var typeDescriptor in descriptor.TypeDescriptors .OfType <INamedTypeDescriptor>()) { if (typeDescriptor.Kind == TypeKind.EntityType && !typeDescriptor.IsInterface()) { INamedTypeDescriptor namedTypeDescriptor = (INamedTypeDescriptor)typeDescriptor.NamedType(); NameString className = namedTypeDescriptor.ExtractMapperName(); var interfaceName = TypeNames.IEntityMapper.WithGeneric( namedTypeDescriptor.ExtractTypeName(), typeDescriptor.RuntimeType.Name); AddSingleton(codeWriter, interfaceName, className); } } codeWriter.WriteLine(); codeWriter.WriteComment("register serializers"); codeWriter.WriteLine(); foreach (var enumType in descriptor.EnumTypeDescriptor) { AddSingleton( codeWriter, TypeNames.ISerializer, CreateEnumParserName(enumType.Name)); } foreach (var serializer in _serializers) { AddSingleton( codeWriter, TypeNames.ISerializer, serializer); } foreach (var inputTypeDescriptor in descriptor.TypeDescriptors .Where(x => x.Kind is TypeKind.InputType)) { AddSingleton( codeWriter, TypeNames.ISerializer, CreateInputValueFormatter( (InputObjectTypeDescriptor)inputTypeDescriptor.NamedType())); } RegisterSerializerResolver().Build(codeWriter); codeWriter.WriteLine(); codeWriter.WriteComment("register operations"); foreach (var operation in descriptor.Operations) { if (!(operation.ResultTypeReference is InterfaceTypeDescriptor typeDescriptor)) { continue; } string connectionKind = operation is SubscriptionOperationDescriptor ? TypeNames.WebSocketConnection : TypeNames.HttpConnection; NameString operationName = operation.OperationName; NameString fullName = operation.Name; NameString operationInterface = typeDescriptor.RuntimeType.Name; // The factories are generated based on the concrete result type, which is the // only implementee of the result type interface. var factoryName = CreateResultFactoryName( typeDescriptor.ImplementedBy.First().RuntimeType.Name); var builderName = CreateResultBuilderName(operationName); stringBuilder.AppendLine( RegisterOperation( connectionKind, descriptor.RuntimeType.Name, fullName, operationInterface, factoryName, builderName)); } stringBuilder.AppendLine( $"{TypeNames.AddSingleton.WithGeneric(descriptor.RuntimeType.Name)}(services);"); stringBuilder.AppendLine(); stringBuilder.AppendLine("return services;"); return(CodeBlockBuilder.From(stringBuilder)); }