diff --git a/readme.md b/readme.md index 1e230aea..c4f3a519 100644 --- a/readme.md +++ b/readme.md @@ -130,7 +130,7 @@ Given a user context class of the following form: ```cs public class MyUserContext : - Dictionary + Dictionary { public MyUserContext(string myProperty) { @@ -174,7 +174,7 @@ ExecutionOptions options = new() Schema = schema, Query = queryString, Inputs = inputs, - UserContext = new Dictionary + UserContext = new Dictionary { { "MyUserContext", @@ -325,7 +325,7 @@ public class QueryTests [Fact] public Task RunInputQuery() { - var field = new Query().GetField("inputQuery"); + var field = new Query().GetField("inputQuery")!; GraphQLUserContext userContext = new(); FluentValidationExtensions.AddCacheToContext( @@ -346,7 +346,7 @@ public class QueryTests }, UserContext = userContext }; - var result = (Result) field.Resolver.Resolve(fieldContext); + var result = (Result) field.Resolver!.Resolve(fieldContext)!; return Verifier.Verify(result); } @@ -354,7 +354,7 @@ public class QueryTests public Task RunInvalidInputQuery() { Thread.CurrentThread.CurrentUICulture = new("en-US"); - var field = new Query().GetField("inputQuery"); + var field = new Query().GetField("inputQuery")!; GraphQLUserContext userContext = new(); FluentValidationExtensions.AddCacheToContext( @@ -373,7 +373,7 @@ public class QueryTests UserContext = userContext }; var exception = Assert.Throws( - () => field.Resolver.Resolve(fieldContext)); + () => field.Resolver!.Resolve(fieldContext)); return Verifier.Verify(exception.Message); } } diff --git a/src/Directory.Build.props b/src/Directory.Build.props index de0913cf..edbaee67 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,6 +1,6 @@ - 6.3.0 + 6.3.1 1.0.0 GraphQL, Validation, FluentValidation Add FluentValidation (https://fluentvalidation.net/) support to GraphQL.net (https://github.com/graphql-dotnet/graphql-dotnet) diff --git a/src/GraphQL.FluentValidation/ArgumentTypeCacheBag.cs b/src/GraphQL.FluentValidation/ArgumentTypeCacheBag.cs index 5c5b57ef..08e11c89 100644 --- a/src/GraphQL.FluentValidation/ArgumentTypeCacheBag.cs +++ b/src/GraphQL.FluentValidation/ArgumentTypeCacheBag.cs @@ -9,9 +9,10 @@ static class ArgumentTypeCacheBag public static void SetCache(this ExecutionOptions options, ValidatorTypeCache cache) { + // ReSharper disable once ConditionIsAlwaysTrueOrFalse if (options.UserContext == null) { - options.UserContext = new Dictionary + options.UserContext = new Dictionary { { key, cache } }; @@ -21,7 +22,7 @@ public static void SetCache(this ExecutionOptions options, ValidatorTypeCache ca AddValidatorCache(options.UserContext, cache); } - internal static void AddValidatorCache(this IDictionary dictionary, ValidatorTypeCache cache) + internal static void AddValidatorCache(this IDictionary dictionary, ValidatorTypeCache cache) { dictionary.Add(key, cache); } @@ -35,7 +36,7 @@ public static ValidatorTypeCache GetCache(this IResolveFieldContext context) if (context.UserContext.TryGetValue(key, out var result)) { - return (ValidatorTypeCache)result; + return (ValidatorTypeCache)result!; } throw new($"Could not extract {nameof(ValidatorTypeCache)} from {nameof(IResolveFieldContext)}.{nameof(IResolveFieldContext.UserContext)}. It is possible {nameof(FluentValidationExtensions)}.{nameof(FluentValidationExtensions.UseFluentValidation)} was not used."); diff --git a/src/GraphQL.FluentValidation/ArgumentValidation.cs b/src/GraphQL.FluentValidation/ArgumentValidation.cs index 2833e100..ab4be400 100644 --- a/src/GraphQL.FluentValidation/ArgumentValidation.cs +++ b/src/GraphQL.FluentValidation/ArgumentValidation.cs @@ -16,13 +16,13 @@ public static class ArgumentValidation /// /// Validate an instance /// - public static Task ValidateAsync(ValidatorTypeCache cache, Type type, TArgument instance, IDictionary userContext) + public static Task ValidateAsync(ValidatorTypeCache cache, Type type, TArgument instance, IDictionary userContext) => ValidateAsync(cache, type, instance, userContext, null); /// /// Validate an instance /// - public static async Task ValidateAsync(ValidatorTypeCache cache, Type type, TArgument instance, IDictionary userContext, IServiceProvider? provider, CancellationToken cancellation = default) + public static async Task ValidateAsync(ValidatorTypeCache cache, Type type, TArgument instance, IDictionary userContext, IServiceProvider? provider, CancellationToken cancellation = default) { var currentType = (Type?)type; var validationContext = default(ValidationContext); @@ -49,13 +49,13 @@ public static async Task ValidateAsync(ValidatorTypeCache cache, Type /// /// Validate an instance /// - public static void Validate(ValidatorTypeCache cache, Type type, TArgument instance, IDictionary userContext) + public static void Validate(ValidatorTypeCache cache, Type type, TArgument instance, IDictionary userContext) => Validate(cache, type, instance, userContext, null); /// /// Validate an instance /// - public static void Validate(ValidatorTypeCache cache, Type type, TArgument instance, IDictionary userContext, IServiceProvider? provider) + public static void Validate(ValidatorTypeCache cache, Type type, TArgument instance, IDictionary userContext, IServiceProvider? provider) { if (instance == null) { @@ -89,7 +89,7 @@ static void ThrowIfResults(IEnumerable results) } } - static ValidationContext BuildValidationContext(TArgument instance, IDictionary userContext) + static ValidationContext BuildValidationContext(TArgument instance, IDictionary userContext) { ValidationContext validationContext = new(instance); validationContext.RootContextData.Add("UserContext", userContext); diff --git a/src/GraphQL.FluentValidation/FluentValidationExtensions_GetArgument.cs b/src/GraphQL.FluentValidation/FluentValidationExtensions_GetArgument.cs index 511880d0..9e4ea559 100644 --- a/src/GraphQL.FluentValidation/FluentValidationExtensions_GetArgument.cs +++ b/src/GraphQL.FluentValidation/FluentValidationExtensions_GetArgument.cs @@ -11,12 +11,21 @@ public static partial class FluentValidationExtensions /// Uses to perform validation. /// If a occurs it will be converted to s by a field middleware. /// - public static TArgument GetValidatedArgument(this IResolveFieldContext context, string name, TArgument defaultValue = default!) + public static TArgument GetValidatedArgument(this IResolveFieldContext context, string name) + { + return GetValidatedArgument(context, name, default!); + } + + /// + /// Wraps to validate the resulting argument instance. + /// Uses to perform validation. + /// If a occurs it will be converted to s by a field middleware. + /// + public static TArgument GetValidatedArgument(this IResolveFieldContext context, string name, TArgument defaultValue) { var argument = context.GetArgument(name, defaultValue); var validatorCache = context.GetCache(); ArgumentValidation.Validate(validatorCache, typeof(TArgument), argument, context.UserContext, context.Schema as IServiceProvider); - //TODO: handle null return argument!; } @@ -25,12 +34,22 @@ public static TArgument GetValidatedArgument(this IResolveFieldContex /// Uses to perform validation. /// If a occurs it will be converted to s by a field middleware. /// - public static object GetValidatedArgument(this IResolveFieldContext context, Type argumentType, string name, object? defaultValue = null) + public static object GetValidatedArgument(this IResolveFieldContext context, Type argumentType, string name) + { + return GetValidatedArgument(context, argumentType, name, null!); + } + + /// + /// Wraps to validate the resulting argument instance. + /// Uses to perform validation. + /// If a occurs it will be converted to s by a field middleware. + /// + public static object GetValidatedArgument(this IResolveFieldContext context, Type argumentType, string name, object defaultValue) { var argument = context.GetArgument(argumentType, name, defaultValue); var validatorCache = context.GetCache(); ArgumentValidation.Validate(validatorCache, argumentType, argument, context.UserContext, context.Schema as IServiceProvider); - return argument; + return argument!; } } } \ No newline at end of file diff --git a/src/GraphQL.FluentValidation/FluentValidationExtensions_GetArgumentAsync.cs b/src/GraphQL.FluentValidation/FluentValidationExtensions_GetArgumentAsync.cs index 2c696d7b..6fe35ea5 100644 --- a/src/GraphQL.FluentValidation/FluentValidationExtensions_GetArgumentAsync.cs +++ b/src/GraphQL.FluentValidation/FluentValidationExtensions_GetArgumentAsync.cs @@ -13,12 +13,21 @@ public static partial class FluentValidationExtensions /// Uses to perform validation. /// If a occurs it will be converted to s by a field middleware. /// - public static async Task GetValidatedArgumentAsync(this IResolveFieldContext context, string name, TArgument defaultValue = default!) + public static Task GetValidatedArgumentAsync(this IResolveFieldContext context, string name) + { + return GetValidatedArgumentAsync(context, name, default!); + } + + /// + /// Wraps to validate the resulting argument instance. + /// Uses to perform validation. + /// If a occurs it will be converted to s by a field middleware. + /// + public static async Task GetValidatedArgumentAsync(this IResolveFieldContext context, string name, TArgument defaultValue) { var argument = context.GetArgument(name, defaultValue); var validatorCache = context.GetCache(); await ArgumentValidation.ValidateAsync(validatorCache, typeof(TArgument), argument, context.UserContext, context.Schema as IServiceProvider); - //TODO: handle null return argument!; } @@ -27,12 +36,22 @@ public static async Task GetValidatedArgumentAsync(this IR /// Uses to perform validation. /// If a occurs it will be converted to s by a field middleware. /// - public static async Task GetValidatedArgumentAsync(this IResolveFieldContext context, Type argumentType, string name, object? defaultValue = null) + public static Task GetValidatedArgumentAsync(this IResolveFieldContext context, Type argumentType, string name) + { + return GetValidatedArgumentAsync(context, argumentType, name, default!); + } + + /// + /// Wraps to validate the resulting argument instance. + /// Uses to perform validation. + /// If a occurs it will be converted to s by a field middleware. + /// + public static async Task GetValidatedArgumentAsync(this IResolveFieldContext context, Type argumentType, string name, object defaultValue) { var argument = context.GetArgument(argumentType, name, defaultValue); var validatorCache = context.GetCache(); await ArgumentValidation.ValidateAsync(validatorCache, argumentType, argument, context.UserContext, context.Schema as IServiceProvider); - return argument; + return argument!; } } } \ No newline at end of file diff --git a/src/GraphQL.FluentValidation/FluentValidationExtensions_UserContext.cs b/src/GraphQL.FluentValidation/FluentValidationExtensions_UserContext.cs index e2adbc37..e9d3a788 100644 --- a/src/GraphQL.FluentValidation/FluentValidationExtensions_UserContext.cs +++ b/src/GraphQL.FluentValidation/FluentValidationExtensions_UserContext.cs @@ -20,7 +20,7 @@ public static T UserContext(this IValidationContext validationContext) /// Injects a instance into a user context for testing purposes. /// public static void AddCacheToContext(T userContext, ValidatorTypeCache cache) - where T : Dictionary + where T : Dictionary { userContext.AddValidatorCache(cache); } diff --git a/src/GraphQL.FluentValidation/GraphQL.FluentValidation.csproj b/src/GraphQL.FluentValidation/GraphQL.FluentValidation.csproj index 8d1b5952..c696240f 100644 --- a/src/GraphQL.FluentValidation/GraphQL.FluentValidation.csproj +++ b/src/GraphQL.FluentValidation/GraphQL.FluentValidation.csproj @@ -4,7 +4,7 @@ - + diff --git a/src/SampleWeb.Tests/QueryTests.cs b/src/SampleWeb.Tests/QueryTests.cs index 49fb33a6..1319e3f3 100644 --- a/src/SampleWeb.Tests/QueryTests.cs +++ b/src/SampleWeb.Tests/QueryTests.cs @@ -15,7 +15,7 @@ public class QueryTests [Fact] public Task RunInputQuery() { - var field = new Query().GetField("inputQuery"); + var field = new Query().GetField("inputQuery")!; GraphQLUserContext userContext = new(); FluentValidationExtensions.AddCacheToContext( @@ -36,7 +36,7 @@ public Task RunInputQuery() }, UserContext = userContext }; - var result = (Result) field.Resolver.Resolve(fieldContext); + var result = (Result) field.Resolver!.Resolve(fieldContext)!; return Verifier.Verify(result); } @@ -44,7 +44,7 @@ public Task RunInputQuery() public Task RunInvalidInputQuery() { Thread.CurrentThread.CurrentUICulture = new("en-US"); - var field = new Query().GetField("inputQuery"); + var field = new Query().GetField("inputQuery")!; GraphQLUserContext userContext = new(); FluentValidationExtensions.AddCacheToContext( @@ -63,7 +63,7 @@ public Task RunInvalidInputQuery() UserContext = userContext }; var exception = Assert.Throws( - () => field.Resolver.Resolve(fieldContext)); + () => field.Resolver!.Resolve(fieldContext)); return Verifier.Verify(exception.Message); } } diff --git a/src/SampleWeb.Tests/SampleWeb.Tests.csproj b/src/SampleWeb.Tests/SampleWeb.Tests.csproj index 3de8b146..487632ef 100644 --- a/src/SampleWeb.Tests/SampleWeb.Tests.csproj +++ b/src/SampleWeb.Tests/SampleWeb.Tests.csproj @@ -3,7 +3,7 @@ net5 - + diff --git a/src/SampleWeb/GraphQlUserContext.cs b/src/SampleWeb/GraphQlUserContext.cs index 26266a85..a6c89523 100644 --- a/src/SampleWeb/GraphQlUserContext.cs +++ b/src/SampleWeb/GraphQlUserContext.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; public class GraphQLUserContext : - Dictionary + Dictionary { } \ No newline at end of file diff --git a/src/SampleWeb/SampleWeb.csproj b/src/SampleWeb/SampleWeb.csproj index 3384acef..532bd84d 100644 --- a/src/SampleWeb/SampleWeb.csproj +++ b/src/SampleWeb/SampleWeb.csproj @@ -6,7 +6,7 @@ - + diff --git a/src/Tests/Arguments/ComplexInputInnerGraph.cs b/src/Tests/Arguments/ComplexInputInnerGraph.cs index 12061756..2b046338 100644 --- a/src/Tests/Arguments/ComplexInputInnerGraph.cs +++ b/src/Tests/Arguments/ComplexInputInnerGraph.cs @@ -7,6 +7,6 @@ public ComplexInputInnerGraph() { Field() .Name("content") - .Resolve(ctx => ctx.Source.Content); + .Resolve(ctx => ctx.Source!.Content); } } \ No newline at end of file diff --git a/src/Tests/Arguments/ComplexInputListItemGraph.cs b/src/Tests/Arguments/ComplexInputListItemGraph.cs index 878d5148..1eeab46b 100644 --- a/src/Tests/Arguments/ComplexInputListItemGraph.cs +++ b/src/Tests/Arguments/ComplexInputListItemGraph.cs @@ -7,10 +7,10 @@ public ComplexInputListItemGraph() { Field>() .Name("id") - .Resolve(ctx => ctx.Source.Id); + .Resolve(ctx => ctx.Source!.Id); Field() .Name("content") - .Resolve(ctx => ctx.Source.Content); + .Resolve(ctx => ctx.Source!.Content); } } \ No newline at end of file diff --git a/src/Tests/Snippets/QueryExecution.cs b/src/Tests/Snippets/QueryExecution.cs index bf5a8c53..5e6e544a 100644 --- a/src/Tests/Snippets/QueryExecution.cs +++ b/src/Tests/Snippets/QueryExecution.cs @@ -46,7 +46,7 @@ async Task ExecuteQuery() #region ContextImplementingDictionary public class MyUserContext : - Dictionary + Dictionary { public MyUserContext(string myProperty) { @@ -86,7 +86,7 @@ void ExecuteQueryWithContextInsideDictionary() Schema = schema, Query = queryString, Inputs = inputs, - UserContext = new Dictionary + UserContext = new Dictionary { { "MyUserContext", diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 5693369f..be07ae43 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -4,7 +4,7 @@ - +