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); }
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)); }