/// <summary> /// Add required services for GraphQL data loader support /// </summary> /// <param name="builder"></param> /// <returns></returns> public static IGraphQLBuilder AddDataLoader(this IGraphQLBuilder builder) { builder.Services.TryAddSingleton <IDataLoaderContextAccessor, DataLoaderContextAccessor>(); builder.Services.AddSingleton <IDocumentExecutionListener, DataLoaderDocumentListener>(); return(builder); }
private static void WithPayload(this IGraphQLBuilder builder, Func <string> payloadFactory, PayloadType payloadType) { builder.Advanced.WithConfiguration(innerBuilder => { if (payloadFactory == null) { throw new ArgumentNullException(nameof(payloadFactory)); } innerBuilder.WithContentEncoding(Encoding.UTF8); innerBuilder.WithMediaType("application/json"); innerBuilder.WithConfiguration(s => { s.WithDefiniteContentType(typeof(GraphQLPayload)); s.ContentFactory = () => { var payload = (payloadFactory() ?? string.Empty).Trim().Replace(Environment.NewLine, "\n").Replace("\t", " "); return(new GraphQLPayload { Query = payload, Variables = s.Items[RelayVariablesKey] as IDictionary <string, object> }); }; }); }); }
/// <summary> /// Set up a delegate to create the UserContext for each GraphQL request /// </summary> /// <typeparam name="TUserContext"></typeparam> /// <param name="builder">The GraphQL builder.</param> /// <param name="creator">A delegate used to create the user context from the <see cref="HttpContext"/>.</param> /// <returns>The GraphQL builder.</returns> public static IGraphQLBuilder AddUserContextBuilder <TUserContext>(this IGraphQLBuilder builder, Func <HttpContext, Task <TUserContext> > creator) where TUserContext : class, IDictionary <string, object> { builder.Services.AddSingleton <IUserContextBuilder>(new UserContextBuilder <TUserContext>(creator)); return(builder); }
public static IGraphQLBuilder AddEntityGraphQueryResolver(this IGraphQLBuilder builder) { #region ComparisonExpression builder.Services.AddSingleton <IComparisonExpressionBuilder, EqualComparisonExpressionBuilder>(); builder.Services.AddSingleton <IComparisonExpressionBuilder, GreaterThanComparisonExpressionBuilder>(); builder.Services.AddSingleton <IComparisonExpressionBuilder, GreaterThanOrEqualComparisonExpressionBuilder>(); builder.Services.AddSingleton <IComparisonExpressionBuilder, LessThanComparisonExpressionBuilder>(); builder.Services.AddSingleton <IComparisonExpressionBuilder, LessThanOrEqualComparisonExpressionBuilder>(); builder.Services.AddSingleton <IComparisonExpressionBuilder, IsNullComparisonExpressionBuilder>(); builder.Services.AddSingleton <IComparisonExpressionBuilder, NotEqualComparisonExpressionBuilder>(); builder.Services.AddSingleton <IComparisonExpressionBuilder, PrefixLikeComparisonExpressionBuilder>(); builder.Services.AddSingleton <IComparisonExpressionBuilder, LikeComparisonExpressionBuilder>(); builder.Services.AddSingleton <IComparisonExpressionBuilder, SuffixLikeComparisonExpressionBuilder>(); builder.Services.TryAddSingleton <IComparisonExpressionFactory, ComparisonExpressionFactory>(); #endregion builder.Services.AddSingleton <IEntityGraphQueryMiddlewareBuilder, LimitGraphQueryMiddlewareBuilder>(); builder.Services.AddSingleton <IEntityGraphQueryMiddlewareBuilder, OffsetGraphQueryMiddlewareBuilder>(); builder.Services.AddSingleton <IEntityGraphQueryMiddlewareBuilder, OrderByGraphQueryMiddlewareBuilder>(); builder.Services.AddSingleton <IEntityGraphQueryMiddlewareBuilder, PredicateGraphQueryMiddlewareBuilder>(); builder.Services.TryAddScoped <IEntityGraphQueryBuilderFactory, EntityGraphQueryBuilderFactory>(); builder.Services.TryAddScoped <IEntityGraphQueryResolver, EntityGraphQueryResolver>(); return(builder); }
/// <summary> /// Scans the specified assembly for classes that implement <see cref="IDIObjectGraphBase{TSource}"/> and /// registers clr type mappings on the schema between that <see cref="DIObjectGraphType{TDIGraph, TSource}"/> /// (constructed from that class and its source type), and the source type. /// Skips classes where the source type is <see cref="object"/>, or where the class is marked with /// the <see cref="DoNotMapClrTypeAttribute"/>, or where another graph type would be automatically mapped /// to the specified type, or where a graph type has already been registered to the specified clr type. /// </summary> public static IGraphQLBuilder AddDIClrTypeMappings(this IGraphQLBuilder builder, Assembly assembly) { var typesAlreadyMapped = new HashSet <Type>( assembly.GetDefaultClrTypeMappings() .Where(x => x.GraphType.IsOutputType()) .Select(x => x.ClrType)); var types = assembly.GetTypes() .Where(x => x.IsClass && !x.IsAbstract && typeof(IDIObjectGraphBase).IsAssignableFrom(x)) .Select <Type, (Type DIGraphType, Type?SourceType)>(x => { var iface = x.GetInterfaces().FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IDIObjectGraphBase <>)); return(x, iface?.GetGenericArguments()[0]); }) .Where(x => x.SourceType != null && x.SourceType != typeof(object) && !x.DIGraphType.IsDefined(typeof(DoNotMapClrTypeAttribute)) && !typesAlreadyMapped.Contains(x.SourceType)) .Select <(Type DIGraphType, Type?SourceType), (Type ClrType, Type GraphType)>(x => (x.SourceType !, typeof(DIObjectGraphType <,>).MakeGenericType(x.DIGraphType, x.SourceType !))) .ToList(); if (types.Count == 0) { return(builder); } builder.ConfigureSchema(schema => { var existingMappings = new HashSet <Type>(schema.TypeMappings.Where(x => x.graphType.IsOutputType()).Select(x => x.clrType)); foreach (var type in types) { if (!existingMappings.Contains(type.ClrType)) { schema.RegisterTypeMapping(type.ClrType, type.GraphType); } } }); return(builder); }
public static IGraphQLBuilder AddLibplanetExplorer <T>(this IGraphQLBuilder builder) where T : IAction, new() { builder.Services.AddLibplanetExplorer <T>(); return(builder); }
/// <summary> /// Adds the GraphQL authorization. /// </summary> /// <param name="builder">The GraphQL builder.</param> /// <param name="options">An action delegate to configure the provided <see cref="AuthorizationOptions"/>.</param> /// <returns>Reference to the passed <paramref name="builder"/>.</returns> public static IGraphQLBuilder AddGraphQLAuthorization(this IGraphQLBuilder builder, Action <AuthorizationOptions> options) { builder.Services .AddHttpContextAccessor() .AddTransient <IValidationRule, AuthorizationValidationRule>() #if NETCOREAPP3_0 .AddAuthorizationCore(options);
/// <summary> /// Registers <see cref="AutoInputObjectGraphType{TSourceType}"/>, <see cref="DIObjectGraphType{TDIGraph}"/> and /// <see cref="DIObjectGraphType{TDIGraph, TSource}"/> as generic types. /// </summary> public static IGraphQLBuilder AddDIGraphTypes(this IGraphQLBuilder builder) { builder.TryRegister(typeof(AutoInputObjectGraphType <>), typeof(AutoInputObjectGraphType <>), ServiceLifetime.Transient); builder.TryRegister(typeof(DIObjectGraphType <>), typeof(DIObjectGraphType <>), ServiceLifetime.Transient); builder.TryRegister(typeof(DIObjectGraphType <,>), typeof(DIObjectGraphType <,>), ServiceLifetime.Transient); return(builder); }
/// <summary> /// Adds an <see cref="IUserContextBuilder"/> as a singleton. /// </summary> /// <typeparam name="TUserContextBuilder">The type of the <see cref="IUserContextBuilder"/> implementation.</typeparam> /// <param name="builder">The GraphQL builder.</param> /// <returns>The GraphQL builder.</returns> public static IGraphQLBuilder AddUserContextBuilder <TUserContextBuilder>(this IGraphQLBuilder builder) where TUserContextBuilder : class, IUserContextBuilder { builder.Services.AddSingleton <IUserContextBuilder, TUserContextBuilder>(); return(builder); }
/// <inheritdoc cref="AddAutomaticPersistedQueries(IGraphQLBuilder, Action{AutomaticPersistedQueriesCacheOptions})"/> public static IGraphQLBuilder AddAutomaticPersistedQueries(this IGraphQLBuilder builder, Action <AutomaticPersistedQueriesCacheOptions, IServiceProvider>?action) { builder.Services .Configure(action) .TryRegister <IConfigureExecution, AutomaticPersistedQueriesExecution>(ServiceLifetime.Singleton, RegistrationCompareMode.ServiceTypeAndImplementationType); return(builder); }
public static IGraphQLBuilder AddWebSocketsHttpMiddleware <TSchema, TMiddleware>(this IGraphQLBuilder builder) where TSchema : ISchema where TMiddleware : GraphQLWebSocketsMiddleware <TSchema> { builder.Services.Register <TMiddleware, TMiddleware>(ServiceLifetime.Singleton); return(builder); }
/// <summary> /// Set up a delegate to create the UserContext for each GraphQL request /// </summary> /// <typeparam name="TUserContext"></typeparam> /// <param name="builder"></param> /// <param name="creator"></param> /// <returns></returns> public static IGraphQLBuilder AddUserContextBuilder <TUserContext>(this IGraphQLBuilder builder, Func <HttpContext, TUserContext> creator) where TUserContext : class { builder.Services.AddSingleton <IUserContextBuilder>(new UserContextBuilder <TUserContext>(creator)); return(builder); }
public static IGraphQLBuilder AddSelfActivatingSchema <TSchema>(this IGraphQLBuilder builder, ServiceLifetime serviceLifetime = ServiceLifetime.Singleton) where TSchema : class, ISchema { if (serviceLifetime == ServiceLifetime.Transient && typeof(IDisposable).IsAssignableFrom(typeof(TSchema))) { // This scenario can cause a memory leak if the schema is requested from the root service provider. // If it was requested from a scoped provider, then there is no reason to register it as transient. // See following link: // https://docs.microsoft.com/en-us/dotnet/core/extensions/dependency-injection-guidelines#disposable-transient-services-captured-by-container throw new InvalidOperationException("A schema that implements IDisposable should not be registered as a transient service. " + "See https://docs.microsoft.com/en-us/dotnet/core/extensions/dependency-injection-guidelines#disposable-transient-services-captured-by-container"); } // Register the service with the DI provider as TSchema, overwriting any existing registration builder.Register(provider => { var selfActivatingServices = new SelfActivatingServiceProvider(provider); var schema = ActivatorUtilities.CreateInstance <TSchema>(selfActivatingServices); return(schema); }, serviceLifetime); // Now register the service as ISchema if not already registered. builder.TryRegister <ISchema>(provider => { var selfActivatingServices = new SelfActivatingServiceProvider(provider); var schema = ActivatorUtilities.CreateInstance <TSchema>(selfActivatingServices); return(schema); }, serviceLifetime); return(builder); }
public GenericType(IGraphQLBuilder builder = null) { try { var typedClass = typeof(T); var props = typedClass.GetProperties(); foreach (var prop in props) { Type propGraphQLType = null; propGraphQLType = prop.PropertyType.TryConvertToGraphQLType(); if (propGraphQLType != null && GraphQLExtensions.IsExtendedGraphQLType(propGraphQLType)) { var resolvedType = propGraphQLType; builder .GetType() .GetInterface("IGraphQLBuilder") .GetMethod("Type") .MakeGenericMethod(resolvedType) .Invoke(builder, null); } else if (propGraphQLType is null) { var resolvedType = propGraphQLType ?? prop.PropertyType; builder .GetType() .GetInterface("IGraphQLBuilder") .GetMethod("Type") .MakeGenericMethod(resolvedType) .Invoke(builder, null); propGraphQLType = typeof(GenericType <>).MakeGenericType(resolvedType); if (propGraphQLType is null) { throw new InvalidCastException( $"{prop.Name} was not automatically convertible into a GraphQL type. " + $"Try explicitly adding this Type through the GraphQL-Core middleware."); } propGraphQLType = GraphQLCoreTypeWrapperGenerator.GetDerivedGenericUserType(propGraphQLType); if (propGraphQLType is null) { throw new NotSupportedException( $"{prop.Name} is a custom type but was not registered through builder. " + $"Try explicitly adding this Type through the Graph-Core middleware"); } } Field(propGraphQLType, prop.Name); } } catch (Exception e) { throw new GraphQLCoreTypeException($"An attempt to create a generic type for type {nameof(T)} failed. Refer to inner exception for details", e); } }
/// <summary> /// Add required services for GraphQL web sockets /// </summary> public static IGraphQLBuilder AddWebSockets(this IGraphQLBuilder builder) { builder.Services .Register(typeof(IWebSocketConnectionFactory <>), typeof(WebSocketConnectionFactory <>), ServiceLifetime.Transient) .Register <IOperationMessageListener, LogMessagesListener>(ServiceLifetime.Transient) .Register <IOperationMessageListener, ProtocolMessageListener>(ServiceLifetime.Transient); return(builder); }
/// <summary> /// Adds a <see cref="IGraphQLRequestDeserializer"/> and a <see cref="IDocumentWriter"/> /// to the service collection with the provided configuration/settings. /// </summary> /// <param name="builder"></param> /// <param name="configureDeserializerSettings"> /// Action to further configure the request deserializer's settings. /// Affects reading of the JSON from the HTTP request the middleware processes. /// </param> /// <param name="configureSerializerSettings"> /// Action to further configure the response serializer's settings. /// Affects JSON returned by the middleware. /// </param> /// <returns>GraphQL Builder.</returns> public static IGraphQLBuilder AddNewtonsoftJson(this IGraphQLBuilder builder, Action <JsonSerializerSettings> configureDeserializerSettings = null, Action <JsonSerializerSettings> configureSerializerSettings = null) { builder.Services.AddSingleton <IGraphQLRequestDeserializer>(p => new GraphQLRequestDeserializer(configureDeserializerSettings ?? (_ => { }))); builder.Services.Replace(ServiceDescriptor.Singleton <IDocumentWriter>(p => new DocumentWriter(configureSerializerSettings ?? (_ => { }), p.GetService <IErrorInfoProvider>() ?? new ErrorInfoProvider()))); return(builder); }
/// <summary> /// Add required services for GraphQL web sockets /// </summary> /// <param name="builder"></param> /// <returns></returns> public static IGraphQLBuilder AddWebSockets(this IGraphQLBuilder builder) { builder.Services .AddTransient(typeof(IWebSocketConnectionFactory <>), typeof(WebSocketConnectionFactory <>)) .AddTransient <IOperationMessageListener, LogMessagesListener>() .AddTransient <IOperationMessageListener, ProtocolMessageListener>(); return(builder); }
/// <summary> /// Provides the ability to configure <see cref="ErrorInfoProviderOptions"/> for the default <see cref="ErrorInfoProvider"/>. /// Also provides integration with Microsoft.Extensions.Options so the caller may use services.Configure{ErrorInfoProviderOptions}(...) /// </summary> /// <param name="builder">GraphQL builder used for GraphQL specific extension methods as 'this' argument.</param> /// <param name="configureOptions">Action to configure the <see cref="ErrorInfoProviderOptions"/>.</param> /// <returns>Reference to <paramref name="builder"/>.</returns> public static IGraphQLBuilder AddErrorInfoProvider(this IGraphQLBuilder builder, Action <ErrorInfoProviderOptions> configureOptions) { if (configureOptions == null) { throw new ArgumentNullException(nameof(configureOptions)); } return(builder.AddErrorInfoProvider((opt, _) => configureOptions(opt))); }
/// <summary> /// Adds the GraphQL Relay types <see cref="ConnectionType<>"/>, <see cref="EdgeType<>"/> /// and <see cref="PageInfoType"/>. /// </summary> /// <param name="builder">The application builder.</param> /// <returns>The application builder.</returns> public static IGraphQLBuilder AddRelayGraphTypes(this IGraphQLBuilder builder) { builder .Services .AddSingleton(typeof(ConnectionType <>)) .AddSingleton(typeof(EdgeType <>)) .AddSingleton <PageInfoType>(); return(builder); }
/// <summary> /// Adds the GraphQL authorization. /// </summary> /// <param name="builder">The GraphQL builder.</param> /// <param name="options">An action delegate to configure the provided <see cref="AuthorizationOptions"/>.</param> /// <returns>The GraphQL builder.</returns> public static IGraphQLBuilder AddGraphQLAuthorization(this IGraphQLBuilder builder, Action <AuthorizationOptions> options) { builder.Services.TryAddSingleton <IHttpContextAccessor, HttpContextAccessor>(); builder .Services .AddTransient <IValidationRule, AuthorizationValidationRule>() .AddAuthorization(options); return(builder); }
public static IServiceCollection AddXCMS(this IServiceCollection services, IGraphQLBuilder graphQlbuilder) { graphQlbuilder.AddGraphTypes(typeof(XCMSAnchor)); services.AddSchemaBuilder <ContentSchema>(); services.AddMediatR(typeof(ContentSchema)); return(services); }
public static TBuilder WithVariable <TBuilder>(this IGraphQLBuilder builder, string name, object value) where TBuilder : IGraphQLBuilder { builder.CreateAndApplyVariables(variables => { variables[name] = value; }); return((TBuilder)builder); }
public static IGraphQLBuilder AddPolicyValidation(this IGraphQLBuilder builder) { builder.Services .AddHttpContextAccessor() .AddTransient <IOperationMessageListener, SubscriptionPrincipalInitializer>() .AddTransient <IValidationRule, PolicyValidationRule>() .AddAuthorizationCore(); return(builder); }
/// <summary> /// Adds the GraphQL authorization. /// </summary> /// <param name="builder">The GraphQL builder.</param> /// <param name="options">An action delegate to configure the provided <see cref="AuthorizationOptions"/>.</param> /// <returns>Reference to the passed <paramref name="builder"/>.</returns> public static IGraphQLBuilder AddGraphQLAuthorization(this IGraphQLBuilder builder, Action <AuthorizationOptions> options) { builder.Services.TryAddTransient <IClaimsPrincipalAccessor, DefaultClaimsPrincipalAccessor>(); builder.Services .AddHttpContextAccessor() .AddTransient <IValidationRule, AuthorizationValidationRule>() .AddAuthorizationCore(options); return(builder); }
/// <summary> /// Add all types that implement <seealso cref="IGraphType"/> in the specified assembly /// </summary> /// <param name="builder"></param> /// <param name="assembly"></param> /// <returns></returns> public static IGraphQLBuilder AddGraphTypes(this IGraphQLBuilder builder, Assembly assembly) { // Register all GraphQL types foreach (var type in assembly.GetTypes() .Where(x => !x.IsAbstract && typeof(IGraphType).IsAssignableFrom(x))) { builder.Services.TryAddTransient(type); } return(builder); }
public static IGraphQLBuilder AddSquidexWriter(this IGraphQLBuilder builder) { builder.Services.AddSingleton <IDocumentWriter>(c => { var serializer = new NewtonsoftJsonSerializer(ConfigureJson(TypeNameHandling.None)); return(new DefaultDocumentWriter(serializer)); }); return(builder); }
public static IGraphQLBuilder AddEntityGraphQueryTypes(this IGraphQLBuilder builder) { builder.Services.TryAddSingleton <OrderBy_Type>(); builder.Services.TryAddSingleton <IntComparisonExpr_Type>(); builder.Services.TryAddSingleton <LongComparisonExpr_Type>(); builder.Services.TryAddSingleton <StringComparisonExpr_Type>(); builder.Services.TryAddSingleton <DecimalComparisonExpr_Type>(); builder.Services.TryAddSingleton <DateTimeComparisonExpr_Type>(); return(builder); }
public static IGraphQLBuilder AddEntityGraphQueryArguments(this IGraphQLBuilder builder) { builder.Services.AddSingleton <IEntityGraphQueryArgumentBuilder, LimitGraphQueryArgumentBuilder>(); builder.Services.AddSingleton <IEntityGraphQueryArgumentBuilder, OffsetGraphQueryArgumentBuilder>(); builder.Services.AddSingleton <IEntityGraphQueryArgumentBuilder, OrderByGraphQueryArgumentBuilder>(); builder.Services.AddSingleton <IEntityGraphQueryArgumentBuilder, PredicateGraphQueryArgumentBuilder>(); builder.Services.TryAddSingleton <IEntityGraphQueryArgumentsBuilder, EntityGraphQueryArgumentsBuilder>(); return(builder); }
public static IGraphQLBuilder AddEntityGraphQuery(this IGraphQLBuilder builder) { builder.Services.TryAddSingleton <IEntityGraphTypeBuilder, EntityGraphTypeBuilder>(); builder.AddEntityGraphQueryTypes(); builder.AddEntityGraphQueryArguments(); builder.AddEntityGraphQueryResolver(); return(builder); }
public static IGraphQLBuilder AddGraphResolvers(this IGraphQLBuilder builder, Assembly assembly) { var types = assembly.GetTypes() .Where(type => !type.IsAbstract && typeof(IDocumentIOResolver).IsAssignableFrom(type)); foreach (var type in types) { builder.Services.Add(ServiceDescriptor.Scoped(type, type)); } return(builder); }