public void SchemaTypesOverwriteDotNetTypes() { // arrange var descriptor = ObjectFieldDescriptor.New(Context, "field"); // act descriptor .Type <NativeType <IReadOnlyDictionary <string, string> > >() .Type <ListType <StringType> >(); // assert ObjectFieldDefinition description = descriptor.CreateDefinition(); ITypeReference typeRef = description.Type; Assert.Equal(typeof(ListType <StringType>), Assert.IsType <ExtendedTypeReference>(typeRef).Type.Source); }
public static ISchemaError ObjectType_UnableToInferOrResolveType( NameString typeName, ObjectType type, ObjectFieldDefinition field) => SchemaErrorBuilder.New() .SetMessage( "Unable to infer or resolve the type of " + "field {0}.{1}. Try to explicitly provide the " + "type like the following: " + "`descriptor.Field(\"field\")" + ".Type<List<StringType>>()`.", typeName, field.Name) .SetCode(ErrorCodes.Schema.NoFieldType) .SetTypeSystemObject(type) .SetPath(Path.New(typeName).Append(field.Name)) .SetExtension(TypeErrorFields.Definition, field) .Build();
private static void CompileMiddleware( Type type, ObjectFieldDefinition definition, FieldMiddleware placeholder, ICompletionContext context) { IFilterConvention filterConvention = context.DescriptorContext.GetFilterConvention(); string sortingConventionArgumentName = context.DescriptorContext.GetSortingNamingConvention().ArgumentName; Type middlewareType = _middlewareDefinition.MakeGenericType(type); FieldMiddleware middleware = FieldClassMiddlewareFactory.Create(middlewareType, SelectionMiddlewareContext.Create( filterConvention, sortingConventionArgumentName)); int index = definition.MiddlewareComponents.IndexOf(placeholder); definition.MiddlewareComponents[index] = middleware; }
private static void CompileMiddleware( ICompletionContext context, ObjectFieldDefinition definition, ITypeReference argumentTypeReference, FieldMiddleware placeholder) { IFilterNamingConvention convention = context.DescriptorContext.GetFilterNamingConvention(); IFilterInputType type = context.GetType <IFilterInputType>(argumentTypeReference); Type middlewareType = _middlewareDefinition .MakeGenericType(type.EntityType); FieldMiddleware middleware = FieldClassMiddlewareFactory.Create(middlewareType, FilterMiddlewareContext.Create(convention.ArgumentName)); int index = definition.MiddlewareComponents.IndexOf(placeholder); definition.MiddlewareComponents[index] = middleware; }
internal ConnectionType( NameString connectionName, ITypeReference nodeType, bool withTotalCount) { if (nodeType is null) { throw new ArgumentNullException(nameof(nodeType)); } ConnectionName = connectionName.EnsureNotEmpty(nameof(connectionName)); NameString edgeTypeName = NameHelper.CreateEdgeName(connectionName); SyntaxTypeReference edgesType = TypeReference.Parse( $"[{edgeTypeName}!]", TypeContext.Output, factory: _ => new EdgeType(connectionName, nodeType)); Definition = CreateTypeDefinition(withTotalCount, edgesType); Definition.Name = NameHelper.CreateConnectionName(connectionName); Definition.Dependencies.Add(new(nodeType)); Definition.Configurations.Add( new CompleteConfiguration( (c, d) => { var definition = (ObjectTypeDefinition)d; ObjectFieldDefinition nodes = definition.Fields.First(IsNodesField); nodes.Type = TypeReference.Parse( $"[{c.GetType<IType>(nodeType).Print()}]", TypeContext.Output); }, Definition, ApplyConfigurationOn.Naming, nodeType, TypeDependencyKind.Named)); Definition.Configurations.Add( new CompleteConfiguration( (c, _) => EdgeType = c.GetType <IEdgeType>(TypeReference.Create(edgeTypeName)), Definition, ApplyConfigurationOn.Completion)); }
public override void OnBeforeCompleteType( ITypeCompletionContext completionContext, DefinitionBase?definition, IDictionary <string, object?> contextData) { // when we are visiting the query type we will add the schema definition field. if ((completionContext.IsQueryType ?? false) && definition is ObjectTypeDefinition objectTypeDefinition) { ObjectFieldDefinition typeNameField = objectTypeDefinition.Fields.First( t => t.Name.Equals(IntrospectionFields.TypeName) && t.IsIntrospectionField); var index = objectTypeDefinition.Fields.IndexOf(typeNameField) + 1; var descriptor = ObjectFieldDescriptor.New( completionContext.DescriptorContext, SchemaDefinitionField); descriptor .Argument(ConfigurationArgument, a => a.Type <NonNullType <StringType> >()) .Type <SchemaDefinitionType>() .Resolve(ctx => { string name = ctx.ArgumentValue <string>(ConfigurationArgument); return(ctx.Schema.ContextData .GetSchemaDefinitions() .FirstOrDefault(t => t.Name.Equals(name))); }); objectTypeDefinition.Fields.Insert(index, descriptor.CreateDefinition()); } // when we visit the schema definition we will copy over the schema definition list // that sits on the schema creation context. else if (definition is SchemaTypeDefinition && completionContext.ContextData.TryGetValue( WellKnownContextData.SchemaDefinitions, out object?schemaDefinitions)) { contextData[WellKnownContextData.SchemaDefinitions] = schemaDefinitions; } }
private static void CompileMiddleware( ITypeCompletionContext context, ObjectFieldDefinition definition, ITypeReference argumentTypeReference, FieldMiddleware placeholder, string?scope) { IFilterInputType type = context.GetType <IFilterInputType>(argumentTypeReference); IFilterConvention convention = context.DescriptorContext.GetFilterConvention(scope); var fieldDescriptor = ObjectFieldDescriptor.From(context.DescriptorContext, definition); convention.ConfigureField(fieldDescriptor); MethodInfo factory = _factoryTemplate.MakeGenericMethod(type.EntityType.Source); var middleware = (FieldMiddleware)factory.Invoke(null, new object[] { convention }) !; var index = definition.MiddlewareComponents.IndexOf(placeholder); definition.MiddlewareComponents[index] = middleware; }
private static void CompileMiddleware( Type type, ObjectFieldDefinition definition, FieldMiddleware placeholder, ITypeCompletionContext context, string?scope) { IProjectionConvention convention = context.DescriptorContext.GetProjectionConvention(scope); RegisterOptimizer(definition.ContextData, convention.CreateOptimizer()); definition.ContextData[ProjectionContextIdentifier] = true; MethodInfo factory = _factoryTemplate.MakeGenericMethod(type); var middleware = (FieldMiddleware)factory.Invoke(null, new object[] { convention }) !; var index = definition.MiddlewareComponents.IndexOf(placeholder); definition.MiddlewareComponents[index] = middleware; }
public void ResolverTypesDoNotOverwriteSchemaTypes() { // arrange var descriptor = ObjectFieldDescriptor.New( Context, typeof(ObjectField).GetProperty("Arguments")); // act descriptor .Name("args") .Type <NonNullType <ListType <NonNullType <__InputValue> > > >() .Resolver(c => c.Parent <ObjectField>().Arguments); // assert ObjectFieldDefinition description = descriptor.CreateDefinition(); ITypeReference typeRef = description.Type; Assert.Equal( typeof(NonNullType <ListType <NonNullType <__InputValue> > >), Assert.IsType <ClrTypeReference>(typeRef).Type); }
public override void OnBeforeRegisterDependencies(ITypeDiscoveryContext context, DefinitionBase?definitionBase, IDictionary <string, object?> contextData) { if (definitionBase is not ObjectTypeDefinition definition) { return; } if (definition.RuntimeType.IsSubclassOf(typeof(BaseEntity))) { foreach (PropertyInfo property in definition.RuntimeType.GetProperties()) { if (property.PropertyType == typeof(NpgsqlTsVector) || property.PropertyType == typeof(NpgsqlTsVector.Lexeme)) { ObjectFieldDefinition fieldDefinition = definition.Fields.First(e => e.Name == context.DescriptorContext.Naming.GetMemberName(property, MemberKind.ObjectField)); int index = definition.Fields.IndexOf(fieldDefinition); definition.Fields.RemoveAt(index); } } } }
private static void ApplyConfiguration( ITypeCompletionContext context, ObjectFieldDefinition definition, Type?entityType, GetPagingProvider?resolvePagingProvider, PagingOptions options, FieldMiddleware placeholder) { options = context.GetSettings(options); entityType ??= context.GetType <IOutputType>(definition.Type).ToRuntimeType(); resolvePagingProvider ??= ResolvePagingProvider; IExtendedType sourceType = GetSourceType(context.TypeInspector, definition, entityType); IPagingProvider pagingProvider = resolvePagingProvider(context.Services, sourceType); IPagingHandler pagingHandler = pagingProvider.CreateHandler(sourceType, options); FieldMiddleware middleware = CreateMiddleware(pagingHandler); var index = definition.MiddlewareComponents.IndexOf(placeholder); definition.MiddlewareComponents[index] = middleware; }
internal static void UseDbContext <TDbContext>( ObjectFieldDefinition definition) where TDbContext : DbContext { var scopedServiceName = typeof(TDbContext).FullName ?? typeof(TDbContext).Name; FieldMiddlewareDefinition placeholderMiddleware = new(_ => _ => throw new NotSupportedException(), key : WellKnownMiddleware.ToList); FieldMiddlewareDefinition contextMiddleware = new(next => async context => { #if NET6_0_OR_GREATER await using TDbContext dbContext = await context.Services .GetRequiredService <IDbContextFactory <TDbContext> >() .CreateDbContextAsync() .ConfigureAwait(false); #else using TDbContext dbContext = context.Services .GetRequiredService <IDbContextFactory <TDbContext> >() .CreateDbContext(); #endif try { context.SetLocalValue(scopedServiceName, dbContext); await next(context).ConfigureAwait(false); } finally { context.RemoveLocalValue(scopedServiceName); } }, key : WellKnownMiddleware.DbContext); definition.MiddlewareDefinitions.Insert(0, placeholderMiddleware); definition.MiddlewareDefinitions.Insert(0, contextMiddleware); AddCompletionMiddleware(definition, placeholderMiddleware); }
public override void OnBeforeCompleteName(ITypeCompletionContext context, DefinitionBase?definitionBase, IDictionary <string, object?> contextData) { if (definitionBase is ObjectTypeDefinition objectTypeDefinition) { if (objectTypeDefinition.RuntimeType.IsSubclassOf(typeof(BaseEntity))) { PropertyInfo idProperty = objectTypeDefinition.RuntimeType.GetProperty(nameof(BaseEntity.Id)) !; ObjectFieldDefinition fieldDefinition = objectTypeDefinition.Fields.First(e => e.Name == context.DescriptorContext.Naming.GetMemberName(idProperty, MemberKind.ObjectField)); ObjectFieldDescriptor fieldDescriptor = ObjectFieldDescriptor.From(context.DescriptorContext, fieldDefinition); fieldDescriptor .IsProjected(true); int index = objectTypeDefinition.Fields.IndexOf(fieldDefinition); objectTypeDefinition.Fields.RemoveAt(index); objectTypeDefinition.Fields.Insert(index, fieldDescriptor.CreateDefinition()); } return; } }
public override void OnBeforeCompleteType( ITypeCompletionContext completionContext, DefinitionBase?definition, IDictionary <string, object?> contextData) { if ((completionContext.IsQueryType ?? false) && definition is ObjectTypeDefinition objectTypeDefinition) { ITypeInspector typeInspector = completionContext.TypeInspector; IIdSerializer serializer = completionContext.Services.GetService <IIdSerializer>() ?? new IdSerializer(); ObjectFieldDefinition typeNameField = objectTypeDefinition.Fields.First( t => t.Name.Equals(IntrospectionFields.TypeName) && t.IsIntrospectionField); var index = objectTypeDefinition.Fields.IndexOf(typeNameField); CreateNodeField(typeInspector, serializer, objectTypeDefinition.Fields, index + 1); CreateNodesField(serializer, objectTypeDefinition.Fields, index + 2); } }
private void AddResolvers( IDictionary <NameString, ObjectFieldDefinition> fields, ISet <string> processed, Type sourceType, Type resolverType) { foreach (MemberInfo member in Context.TypeInspector.GetMembers(resolverType)) { if (IsResolverRelevant(sourceType, member)) { ObjectFieldDefinition fieldDefinition = ObjectFieldDescriptor .New(Context, member, sourceType, resolverType) .CreateDefinition(); if (processed.Add(fieldDefinition.Name)) { fields[fieldDefinition.Name] = fieldDefinition; } } } }
private static Type GetArgumentType( ObjectFieldDefinition definition, Type?filterType, ITypeInspector typeInspector) { Type?argumentType = filterType; if (argumentType is null) { if (definition.ResultType is null || definition.ResultType == typeof(object) || !typeInspector.TryCreateTypeInfo( definition.ResultType, out ITypeInfo? typeInfo)) { throw new SchemaException( SchemaErrorBuilder.New() .SetMessage("Cannot handle the specified type.") .SetExtension("fieldName", definition.Name) .Build()); } argumentType = typeof(SortInputType <>).MakeGenericType(typeInfo.NamedType); } if (argumentType == typeof(object)) { // TODO : resources throw new SchemaException( SchemaErrorBuilder.New() .SetMessage( "The sort type cannot be " + "inferred from `System.Object`.") .SetCode(ErrorCodes.Filtering.FilterObjectType) .Build()); } return(argumentType); }
public void SetResolverAndInferTypeIsAlwaysRecognisedAsDotNetType() { // arrange var descriptor = ObjectFieldDescriptor.New( Context, typeof(ObjectField).GetProperty("Arguments")); // act descriptor .Type <__Type>() .Resolver(ctx => ctx.Schema .GetType <INamedType>(ctx.Argument <string>("type"))); // assert ObjectFieldDefinition description = descriptor.CreateDefinition(); ITypeReference typeRef = description.Type; Assert.Equal( typeof(__Type), Assert.IsType <ClrTypeReference>(typeRef).Type); Assert.NotNull(description.Resolver); }
private static Type GetArgumentType( ObjectFieldDefinition definition, Type filterType) { Type argumentType = filterType; if (filterType == null) { if (!TypeInspector.Default.TryCreate( definition.ResultType, out TypeInfo typeInfo)) { // TODO : resources throw new ArgumentException( "Cannot handle the specified type.", definition.ResultType.FullName); } argumentType = typeof(SortInputType <>).MakeGenericType( typeInfo.ClrType); } if (argumentType == typeof(object)) { // TODO : resources throw new SchemaException( SchemaErrorBuilder.New() .SetMessage( "The sort type cannot be " + "infered from `System.Object`.") .SetCode(ErrorCodes.Filtering.FilterObjectType) .Build()); } return(argumentType); }
private static IExtendedType GetSourceType( ITypeInspector typeInspector, ObjectFieldDefinition definition, Type entityType) { // if an explicit result type is defined we will type it since it expresses the // intend. if (definition.ResultType is not null) { return(typeInspector.GetType(definition.ResultType)); } // Otherwise we will look at specified members and extract the return type. MemberInfo?member = definition.ResolverMember ?? definition.Member; if (member is not null) { return(typeInspector.GetReturnType(member, true)); } // if we were not able to resolve the source type we will assume that it is // an enumerable of the entity type. return(typeInspector.GetType(typeof(IEnumerable <>).MakeGenericType(entityType))); }
private static void DeclareFieldArguments( ObjectFieldDefinition parent, FieldDefinitionNode field, bool preserveSyntaxNodes) { foreach (InputValueDefinitionNode argument in field.Arguments) { var argumentDefinition = new ArgumentDefinition( argument.Name.Value, argument.Description?.Value, TypeReference.Create(argument.Type), argument.DefaultValue); argumentDefinition.BindTo = argument.GetBindingValue(); if (preserveSyntaxNodes) { argumentDefinition.SyntaxNode = argument; } SdlToTypeSystemHelper.AddDirectives(argumentDefinition, argument); parent.Arguments.Add(argumentDefinition); } }
private static void AddSerializerToObjectField( ITypeCompletionContext completionContext, ObjectFieldDefinition definition, FieldMiddleware placeholder, NameString typeName) { ITypeInspector typeInspector = completionContext.TypeInspector; IExtendedType? resultType; if (definition.ResultType is not null) { resultType = typeInspector.GetType(definition.ResultType); } else if (definition.Type is ExtendedTypeReference typeReference) { resultType = typeReference.Type; } else { throw new SchemaException(SchemaErrorBuilder.New() .SetMessage("Unable to resolve type from field `{0}`.", definition.Name) .SetTypeSystemObject(completionContext.Type) .Build()); } NameString schemaName = default; completionContext.DescriptorContext.SchemaCompleted += (sender, args) => schemaName = args.Schema.Name; IIdSerializer serializer = completionContext.Services.GetService <IIdSerializer>() ?? new IdSerializer(); var index = definition.MiddlewareComponents.IndexOf(placeholder); if (typeName.IsEmpty) { typeName = completionContext.Type.Name; } definition.MiddlewareComponents[index] = next => async context => { await next(context).ConfigureAwait(false); if (context.Result is not null) { if (resultType.IsArrayOrList) { var list = new List <object?>(); foreach (object?element in (IEnumerable)context.Result) { list.Add(element is null ? element : serializer.Serialize(schemaName, typeName, element)); } context.Result = list; } else { context.Result = serializer.Serialize(schemaName, typeName, context.Result); } } }; }
internal static void UseResolverService( ObjectFieldDefinition definition, Type serviceType) => _useResolverService .MakeGenericMethod(serviceType) .Invoke(null, new object?[] { definition });
public static ObjectFieldDescriptor ToDescriptor( this ObjectFieldDefinition definition, IDescriptorContext context) => ObjectFieldDescriptor.From(context, definition);
static ObjectField CreateField(ObjectFieldDefinition fieldDef, int index) => new(fieldDef, index);
private static void AddSerializerToObjectField( ITypeCompletionContext completionContext, ObjectFieldDefinition definition, ResultConverterDefinition placeholder, NameString typeName) { ITypeInspector typeInspector = completionContext.TypeInspector; IExtendedType? resultType; if (definition.ResultType is not null) { resultType = typeInspector.GetType(definition.ResultType); } else if (definition.Type is ExtendedTypeReference typeReference) { resultType = typeReference.Type; } else { throw new SchemaException(SchemaErrorBuilder.New() .SetMessage("Unable to resolve type from field `{0}`.", definition.Name) .SetTypeSystemObject(completionContext.Type) .Build()); } NameString schemaName = default; completionContext.DescriptorContext.SchemaCompleted += (_, args) => schemaName = args.Schema.Name; IIdSerializer serializer = completionContext.Services.GetService <IIdSerializer>() ?? new IdSerializer(); var index = definition.ResultConverters.IndexOf(placeholder); if (typeName.IsEmpty) { typeName = completionContext.Type.Name; } definition.ResultConverters[index] = new((_, result) => { if (result is not null) { if (resultType.IsArrayOrList) { var list = new List <object?>(); foreach (var element in (IEnumerable)result) { list.Add(element is null ? element : serializer.Serialize(schemaName, typeName, element)); } return(list); } return(serializer.Serialize(schemaName, typeName, result)); } return(result); }, key : WellKnownMiddleware.GlobalId, isRepeatable : false); }
internal static void UsePooledService <TService>( ObjectFieldDefinition definition) where TService : class => UsePooledServiceInternal <TService>(definition);