From 8a61a51f94e1c28124dfa8279e5855bf01493d46 Mon Sep 17 00:00:00 2001 From: Glen Date: Thu, 12 Dec 2024 11:12:32 +0200 Subject: [PATCH 1/5] Refactored Fusion Composition validation --- .../Collections/MultiValueDictionary.cs | 28 +++ .../Fusion.Composition/Errors/ErrorHelper.cs | 5 +- .../Events/EventAggregator.cs | 29 +++ .../Logging/CompositionLog.cs | 12 +- .../Logging/Contracts/ICompositionLog.cs | 10 +- .../Logging/LoggingSession.cs | 37 ---- .../IEachDirectiveArgumentEventHandler.cs | 6 + .../Contracts/IEachDirectiveEventHandler.cs | 6 + .../IEachFieldArgumentEventHandler.cs | 6 + .../Contracts/IEachOutputFieldEventHandler.cs | 6 + .../IEachOutputFieldNameEventHandler.cs | 6 + .../Contracts/IEachTypeEventHandler.cs | 6 + .../Contracts/IPreMergeValidationRule.cs | 8 - .../PreMergeValidation/Events.cs | 51 ++++++ .../PreMergeValidationContext.cs | 77 -------- .../PreMergeValidation/PreMergeValidator.cs | 171 ++++++++++++++++-- .../DisallowedInaccessibleElementsRule.cs | 125 ++++++------- .../Rules/OutputFieldTypesMergeableRule.cs | 26 +-- .../CompositionResources.Designer.cs | 6 +- .../Properties/CompositionResources.resx | 4 +- .../Fusion.Composition/SourceSchemaMerger.cs | 10 +- ...DisallowedInaccessibleElementsRuleTests.cs | 16 +- .../OutputFieldTypesMergeableRuleTests.cs | 16 +- 23 files changed, 402 insertions(+), 265 deletions(-) create mode 100644 src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Collections/MultiValueDictionary.cs create mode 100644 src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Events/EventAggregator.cs delete mode 100644 src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Logging/LoggingSession.cs create mode 100644 src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachDirectiveArgumentEventHandler.cs create mode 100644 src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachDirectiveEventHandler.cs create mode 100644 src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachFieldArgumentEventHandler.cs create mode 100644 src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachOutputFieldEventHandler.cs create mode 100644 src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachOutputFieldNameEventHandler.cs create mode 100644 src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachTypeEventHandler.cs delete mode 100644 src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IPreMergeValidationRule.cs create mode 100644 src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Events.cs delete mode 100644 src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/PreMergeValidationContext.cs diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Collections/MultiValueDictionary.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Collections/MultiValueDictionary.cs new file mode 100644 index 00000000000..94f49f1c3bd --- /dev/null +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Collections/MultiValueDictionary.cs @@ -0,0 +1,28 @@ +namespace HotChocolate.Fusion.Collections; + +internal sealed class MultiValueDictionary + : Dictionary> where TKey : notnull +{ + public void Add(TKey key, TValue value) + { + ArgumentNullException.ThrowIfNull(key); + + if (!TryGetValue(key, out var list)) + { + list = []; + Add(key, list); + } + + list.Add(value); + } + + public void Remove(TKey key, TValue value) + { + ArgumentNullException.ThrowIfNull(key); + + if (TryGetValue(key, out var list)) + { + list.Remove(value); + } + } +} diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Errors/ErrorHelper.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Errors/ErrorHelper.cs index 4841f244835..800b1db42f9 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Errors/ErrorHelper.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Errors/ErrorHelper.cs @@ -1,10 +1,9 @@ -using HotChocolate.Fusion.PreMergeValidation.Contracts; using static HotChocolate.Fusion.Properties.CompositionResources; namespace HotChocolate.Fusion.Errors; internal static class ErrorHelper { - public static CompositionError PreMergeValidationRuleFailed(IPreMergeValidationRule rule) - => new(string.Format(ErrorHelper_PreMergeValidationRuleFailed, rule.GetType().Name)); + public static CompositionError PreMergeValidationFailed() + => new(ErrorHelper_PreMergeValidationFailed); } diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Events/EventAggregator.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Events/EventAggregator.cs new file mode 100644 index 00000000000..496e1c60867 --- /dev/null +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Events/EventAggregator.cs @@ -0,0 +1,29 @@ +using HotChocolate.Fusion.Collections; + +namespace HotChocolate.Fusion.Events; + +internal sealed class EventAggregator +{ + private readonly MultiValueDictionary _subscribers = new(); + + public void Subscribe(Action handler) + { + _subscribers.Add(typeof(TEvent), handler); + } + + public void Unsubscribe(Action handler) + { + _subscribers.Remove(typeof(TEvent), handler); + } + + public void Publish(TEvent @event) + { + if (_subscribers.ContainsKey(typeof(TEvent))) + { + foreach (var handler in _subscribers[typeof(TEvent)]) + { + ((Action)handler)(@event); + } + } + } +} diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Logging/CompositionLog.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Logging/CompositionLog.cs index 2f9cc4b9cea..3f51bdfed5f 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Logging/CompositionLog.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Logging/CompositionLog.cs @@ -5,6 +5,8 @@ namespace HotChocolate.Fusion.Logging; public sealed class CompositionLog : ICompositionLog, IEnumerable { + public bool HasErrors { get; private set; } + public bool IsEmpty => _entries.Count == 0; private readonly List _entries = []; @@ -13,12 +15,12 @@ public void Write(LogEntry entry) { ArgumentNullException.ThrowIfNull(entry); - _entries.Add(entry); - } + if (entry.Severity == LogSeverity.Error) + { + HasErrors = true; + } - public ILoggingSession CreateSession() - { - return new LoggingSession(this); + _entries.Add(entry); } public IEnumerator GetEnumerator() => _entries.GetEnumerator(); diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Logging/Contracts/ICompositionLog.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Logging/Contracts/ICompositionLog.cs index 1251c6adf64..84e325c8089 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Logging/Contracts/ICompositionLog.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Logging/Contracts/ICompositionLog.cs @@ -5,6 +5,10 @@ namespace HotChocolate.Fusion.Logging.Contracts; /// public interface ICompositionLog { + // FIXME: Docs. + bool HasErrors { get; } + + // FIXME: Docs. bool IsEmpty { get; } /// @@ -12,10 +16,4 @@ public interface ICompositionLog /// /// The to write. void Write(LogEntry entry); - - /// - /// Creates a new logging session that keeps track of the number of info, warning, and error - /// entries logged. - /// - ILoggingSession CreateSession(); } diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Logging/LoggingSession.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Logging/LoggingSession.cs deleted file mode 100644 index 6ee1b23df63..00000000000 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Logging/LoggingSession.cs +++ /dev/null @@ -1,37 +0,0 @@ -using HotChocolate.Fusion.Logging.Contracts; - -namespace HotChocolate.Fusion.Logging; - -public sealed class LoggingSession(ICompositionLog compositionLog) : ILoggingSession -{ - public int InfoCount { get; private set; } - - public int WarningCount { get; private set; } - - public int ErrorCount { get; private set; } - - public void Write(LogEntry entry) - { - ArgumentNullException.ThrowIfNull(entry); - - switch (entry.Severity) - { - case LogSeverity.Info: - InfoCount++; - break; - - case LogSeverity.Warning: - WarningCount++; - break; - - case LogSeverity.Error: - ErrorCount++; - break; - - default: - throw new InvalidOperationException(); - } - - compositionLog.Write(entry); - } -} diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachDirectiveArgumentEventHandler.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachDirectiveArgumentEventHandler.cs new file mode 100644 index 00000000000..801352fd4bb --- /dev/null +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachDirectiveArgumentEventHandler.cs @@ -0,0 +1,6 @@ +namespace HotChocolate.Fusion.PreMergeValidation.Contracts; + +internal interface IEachDirectiveArgumentEventHandler +{ + void OnEachDirectiveArgument(EachDirectiveArgumentEvent @event); +} diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachDirectiveEventHandler.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachDirectiveEventHandler.cs new file mode 100644 index 00000000000..53cf8f5020c --- /dev/null +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachDirectiveEventHandler.cs @@ -0,0 +1,6 @@ +namespace HotChocolate.Fusion.PreMergeValidation.Contracts; + +internal interface IEachDirectiveEventHandler +{ + void OnEachDirective(EachDirectiveEvent @event); +} diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachFieldArgumentEventHandler.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachFieldArgumentEventHandler.cs new file mode 100644 index 00000000000..f0d204a1ae3 --- /dev/null +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachFieldArgumentEventHandler.cs @@ -0,0 +1,6 @@ +namespace HotChocolate.Fusion.PreMergeValidation.Contracts; + +internal interface IEachFieldArgumentEventHandler +{ + void OnEachFieldArgument(EachFieldArgumentEvent @event); +} diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachOutputFieldEventHandler.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachOutputFieldEventHandler.cs new file mode 100644 index 00000000000..ecc19bf9f67 --- /dev/null +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachOutputFieldEventHandler.cs @@ -0,0 +1,6 @@ +namespace HotChocolate.Fusion.PreMergeValidation.Contracts; + +internal interface IEachOutputFieldEventHandler +{ + void OnEachOutputField(EachOutputFieldEvent @event); +} diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachOutputFieldNameEventHandler.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachOutputFieldNameEventHandler.cs new file mode 100644 index 00000000000..96d74460032 --- /dev/null +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachOutputFieldNameEventHandler.cs @@ -0,0 +1,6 @@ +namespace HotChocolate.Fusion.PreMergeValidation.Contracts; + +internal interface IEachOutputFieldNameEventHandler +{ + void OnEachOutputFieldName(EachOutputFieldNameEvent @event); +} diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachTypeEventHandler.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachTypeEventHandler.cs new file mode 100644 index 00000000000..071d939ad13 --- /dev/null +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachTypeEventHandler.cs @@ -0,0 +1,6 @@ +namespace HotChocolate.Fusion.PreMergeValidation.Contracts; + +internal interface IEachTypeEventHandler +{ + void OnEachType(EachTypeEvent @event); +} diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IPreMergeValidationRule.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IPreMergeValidationRule.cs deleted file mode 100644 index a9a60320a91..00000000000 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IPreMergeValidationRule.cs +++ /dev/null @@ -1,8 +0,0 @@ -using HotChocolate.Fusion.Results; - -namespace HotChocolate.Fusion.PreMergeValidation.Contracts; - -internal interface IPreMergeValidationRule -{ - CompositionResult Run(PreMergeValidationContext context); -} diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Events.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Events.cs new file mode 100644 index 00000000000..fd2978f5411 --- /dev/null +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Events.cs @@ -0,0 +1,51 @@ +using System.Collections.Immutable; +using HotChocolate.Skimmed; + +namespace HotChocolate.Fusion.PreMergeValidation; + +internal record EachDirectiveArgumentEvent( + CompositionContext Context, + InputFieldDefinition Argument, + DirectiveDefinition Directive, + SchemaDefinition Schema); + +internal record EachDirectiveEvent( + CompositionContext Context, + DirectiveDefinition Directive, + SchemaDefinition Schema); + +internal record EachFieldArgumentEvent( + CompositionContext Context, + InputFieldDefinition Argument, + OutputFieldDefinition Field, + INamedTypeDefinition Type, + SchemaDefinition Schema); + +internal record EachFieldArgumentNameEvent( + CompositionContext Context, + string ArgumentName, + ImmutableArray ArgumentInfo, + string FieldName, + string TypeName); + +internal record EachOutputFieldEvent( + CompositionContext Context, + OutputFieldDefinition Field, + INamedTypeDefinition Type, + SchemaDefinition Schema); + +internal record EachOutputFieldNameEvent( + CompositionContext Context, + string FieldName, + ImmutableArray FieldInfo, + string TypeName); + +internal record EachTypeEvent( + CompositionContext Context, + INamedTypeDefinition Type, + SchemaDefinition Schema); + +internal record EachTypeNameEvent( + CompositionContext Context, + string TypeName, + ImmutableArray TypeInfo); diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/PreMergeValidationContext.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/PreMergeValidationContext.cs deleted file mode 100644 index 538df65d0ca..00000000000 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/PreMergeValidationContext.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System.Collections.Immutable; -using HotChocolate.Fusion.Logging.Contracts; -using HotChocolate.Skimmed; - -namespace HotChocolate.Fusion.PreMergeValidation; - -internal sealed class PreMergeValidationContext(CompositionContext context) -{ - public ImmutableArray SchemaDefinitions => context.SchemaDefinitions; - public ICompositionLog Log => context.Log; - public ImmutableArray OutputTypeInfo = []; - - public void Initialize() - { - InitializeOutputTypeInfo(); - } - - /// - /// Initializes a structure that makes it easier to access combined output types, fields, and - /// arguments for validation purposes. - /// - private void InitializeOutputTypeInfo() - { - OutputTypeInfo = - [ - .. SchemaDefinitions - .SelectMany(s => s.Types) - .Where(t => t.IsOutputType()) - .OfType() - .GroupBy( - t => t.Name, - (typeName, types) => - { - types = types.ToImmutableArray(); - - var fieldInfo = types - .SelectMany(t => t.Fields) - .GroupBy( - f => f.Name, - (fieldName, fields) => - { - fields = fields.ToImmutableArray(); - - var argumentInfo = fields - .SelectMany(f => f.Arguments) - .GroupBy( - a => a.Name, - (argumentName, arguments) => - new OutputArgumentInfo( - argumentName, - [.. arguments])); - - return new OutputFieldInfo( - fieldName, - [.. fields], - [.. argumentInfo]); - }); - - return new OutputTypeInfo(typeName, [.. types], [.. fieldInfo]); - }) - ]; - } -} - -internal record OutputTypeInfo( - string TypeName, - ImmutableArray Types, - ImmutableArray FieldInfo); - -internal record OutputFieldInfo( - string FieldName, - ImmutableArray Fields, - ImmutableArray Arguments); - -internal record OutputArgumentInfo( - string ArgumentName, - ImmutableArray Arguments); diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/PreMergeValidator.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/PreMergeValidator.cs index 1d812523f12..8c949f815a2 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/PreMergeValidator.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/PreMergeValidator.cs @@ -1,36 +1,175 @@ -using System.Collections.Immutable; +using HotChocolate.Fusion.Collections; using HotChocolate.Fusion.Errors; +using HotChocolate.Fusion.Events; using HotChocolate.Fusion.PreMergeValidation.Contracts; -using HotChocolate.Fusion.PreMergeValidation.Rules; using HotChocolate.Fusion.Results; +using HotChocolate.Skimmed; namespace HotChocolate.Fusion.PreMergeValidation; internal sealed class PreMergeValidator { - private readonly ImmutableArray _validationRules = - [ - new DisallowedInaccessibleElementsRule(), - new OutputFieldTypesMergeableRule() - ]; + private readonly EventAggregator _eventAggregator; - public CompositionResult Validate(CompositionContext compositionContext) + public PreMergeValidator(IEnumerable rules) { - var preMergeValidationContext = new PreMergeValidationContext(compositionContext); - preMergeValidationContext.Initialize(); + _eventAggregator = new EventAggregator(); - var errors = new List(); + SubscribeRules(rules); + } + + public CompositionResult Validate(CompositionContext context) + { + PublishEvents(context); + + return context.Log.HasErrors + ? ErrorHelper.PreMergeValidationFailed() + : CompositionResult.Success(); + } + + private void SubscribeRules(IEnumerable rules) + { + foreach (var rule in rules) + { + if (rule is IEachTypeEventHandler eachTypeEventHandler) + { + _eventAggregator.Subscribe( + eachTypeEventHandler.OnEachType); + } + + if (rule is IEachOutputFieldEventHandler eachOutputFieldEventHandler) + { + _eventAggregator.Subscribe( + eachOutputFieldEventHandler.OnEachOutputField); + } + + if (rule is IEachFieldArgumentEventHandler eachFieldArgumentEventHandler) + { + _eventAggregator.Subscribe( + eachFieldArgumentEventHandler.OnEachFieldArgument); + } + + if (rule is IEachDirectiveEventHandler eachDirectiveEventHandler) + { + _eventAggregator.Subscribe( + eachDirectiveEventHandler.OnEachDirective); + } + + if (rule is IEachDirectiveArgumentEventHandler eachDirectiveArgumentEventHandler) + { + _eventAggregator.Subscribe( + eachDirectiveArgumentEventHandler.OnEachDirectiveArgument); + } + + if (rule is IEachOutputFieldNameEventHandler eachOutputFieldNameEventHandler) + { + _eventAggregator.Subscribe( + eachOutputFieldNameEventHandler.OnEachOutputFieldName); + } + } + } + + private void PublishEvents(CompositionContext context) + { + MultiValueDictionary typeInfoByName = []; - foreach (var validationRule in _validationRules) + foreach (var schema in context.SchemaDefinitions) { - var result = validationRule.Run(preMergeValidationContext); + foreach (var type in schema.Types) + { + _eventAggregator.Publish(new EachTypeEvent(context, type, schema)); + + typeInfoByName.Add(type.Name, new TypeInfo(type, schema)); + + if (type is ComplexTypeDefinition complexType) + { + foreach (var field in complexType.Fields) + { + _eventAggregator.Publish( + new EachOutputFieldEvent(context, field, type, schema)); - if (result.IsFailure) + foreach (var argument in field.Arguments) + { + _eventAggregator.Publish( + new EachFieldArgumentEvent(context, argument, field, type, schema)); + } + } + } + } + + foreach (var directive in schema.DirectiveDefinitions) { - errors.AddRange(result.Errors); + _eventAggregator.Publish( + new EachDirectiveEvent(context, directive, schema)); + + foreach (var argument in directive.Arguments) + { + _eventAggregator.Publish( + new EachDirectiveArgumentEvent(context, argument, directive, schema)); + } } } - return errors; + foreach (var (typeName, typeInfo) in typeInfoByName) + { + _eventAggregator.Publish(new EachTypeNameEvent(context, typeName, [.. typeInfo])); + + MultiValueDictionary fieldInfoByName = []; + + foreach (var (type, schema) in typeInfo) + { + if (type is ComplexTypeDefinition complexType) + { + foreach (var field in complexType.Fields) + { + fieldInfoByName.Add(field.Name, new OutputFieldInfo(field, type, schema)); + } + } + } + + foreach (var (fieldName, fieldInfo) in fieldInfoByName) + { + _eventAggregator.Publish( + new EachOutputFieldNameEvent(context, fieldName, [.. fieldInfo], typeName)); + + MultiValueDictionary argumentInfoByName = []; + + foreach (var (field, type, schema) in fieldInfo) + { + foreach (var argument in field.Arguments) + { + argumentInfoByName.Add( + argument.Name, + new FieldArgumentInfo(argument, field, type, schema)); + } + } + + foreach (var (argumentName, argumentInfo) in argumentInfoByName) + { + _eventAggregator.Publish( + new EachFieldArgumentNameEvent( + context, + argumentName, + [.. argumentInfo], + fieldName, + typeName)); + } + } + } } } + +internal record TypeInfo( + INamedTypeDefinition Type, + SchemaDefinition Schema); + +internal record OutputFieldInfo( + OutputFieldDefinition Field, + INamedTypeDefinition Type, + SchemaDefinition Schema); + +internal record FieldArgumentInfo( + InputFieldDefinition Argument, + OutputFieldDefinition Field, + INamedTypeDefinition Type, + SchemaDefinition Schema); diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Rules/DisallowedInaccessibleElementsRule.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Rules/DisallowedInaccessibleElementsRule.cs index b01d1f11c78..95fb7e5df79 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Rules/DisallowedInaccessibleElementsRule.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Rules/DisallowedInaccessibleElementsRule.cs @@ -1,6 +1,4 @@ -using HotChocolate.Fusion.Errors; using HotChocolate.Fusion.PreMergeValidation.Contracts; -using HotChocolate.Fusion.Results; using HotChocolate.Skimmed; using static HotChocolate.Fusion.Logging.LogEntryHelper; @@ -15,80 +13,73 @@ namespace HotChocolate.Fusion.PreMergeValidation.Rules; /// /// Specification /// -internal sealed class DisallowedInaccessibleElementsRule : IPreMergeValidationRule +internal sealed class DisallowedInaccessibleElementsRule + : IEachTypeEventHandler + , IEachOutputFieldEventHandler + , IEachFieldArgumentEventHandler + , IEachDirectiveArgumentEventHandler { - public CompositionResult Run(PreMergeValidationContext context) + public void OnEachType(EachTypeEvent @event) { - var loggingSession = context.Log.CreateSession(); + var (context, type, schema) = @event; - foreach (var schema in context.SchemaDefinitions) + // Built-in scalar types must be accessible. + if (type is ScalarTypeDefinition { IsSpecScalar: true } scalar + && !ValidationHelper.IsAccessible(scalar)) { - foreach (var type in schema.Types) - { - if (type is ScalarTypeDefinition { IsSpecScalar: true } scalar - && !ValidationHelper.IsAccessible(type)) - { - loggingSession.Write(DisallowedInaccessibleScalar(scalar, schema)); - } + context.Log.Write(DisallowedInaccessibleScalar(scalar, schema)); + } + + // Introspection types must be accessible. + if (type.IsIntrospectionType && !ValidationHelper.IsAccessible(type)) + { + context.Log.Write(DisallowedInaccessibleIntrospectionType(type, schema)); + } + } - if (type.IsIntrospectionType) - { - if (!ValidationHelper.IsAccessible(type)) - { - loggingSession.Write(DisallowedInaccessibleIntrospectionType(type, schema)); - } + public void OnEachOutputField(EachOutputFieldEvent @event) + { + var (context, field, type, schema) = @event; - if (type is ComplexTypeDefinition complexType) - { - foreach (var field in complexType.Fields) - { - if (!ValidationHelper.IsAccessible(field)) - { - loggingSession.Write( - DisallowedInaccessibleIntrospectionField( - field, - type.Name, - schema)); - } + // Introspection fields must be accessible. + if (type.IsIntrospectionType && !ValidationHelper.IsAccessible(field)) + { + context.Log.Write( + DisallowedInaccessibleIntrospectionField( + field, + type.Name, + schema)); + } + } - foreach (var argument in field.Arguments) - { - if (!ValidationHelper.IsAccessible(argument)) - { - loggingSession.Write( - DisallowedInaccessibleIntrospectionArgument( - argument, - field.Name, - type.Name, - schema)); - } - } - } - } - } - } + public void OnEachFieldArgument(EachFieldArgumentEvent @event) + { + var (context, argument, field, type, schema) = @event; - foreach (var directive in schema.DirectiveDefinitions) - { - if (BuiltIns.IsBuiltInDirective(directive.Name)) - { - foreach (var argument in directive.Arguments) - { - if (!ValidationHelper.IsAccessible(argument)) - { - loggingSession.Write( - DisallowedInaccessibleDirectiveArgument( - argument, - directive.Name, - schema)); - } - } - } - } + // Introspection arguments must be accessible. + if (type.IsIntrospectionType && !ValidationHelper.IsAccessible(argument)) + { + context.Log.Write( + DisallowedInaccessibleIntrospectionArgument( + argument, + field.Name, + type.Name, + schema)); } + } - return loggingSession.ErrorCount == 0 - ? CompositionResult.Success() - : ErrorHelper.PreMergeValidationRuleFailed(this); + public void OnEachDirectiveArgument(EachDirectiveArgumentEvent @event) + { + var (context, argument, directive, schema) = @event; + + // Built-in directive arguments must be accessible. + if (BuiltIns.IsBuiltInDirective(directive.Name) && !ValidationHelper.IsAccessible(argument)) + { + context.Log.Write( + DisallowedInaccessibleDirectiveArgument( + argument, + directive.Name, + schema)); + } } } diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Rules/OutputFieldTypesMergeableRule.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Rules/OutputFieldTypesMergeableRule.cs index e93c6e91b14..5cec7b28ba6 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Rules/OutputFieldTypesMergeableRule.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Rules/OutputFieldTypesMergeableRule.cs @@ -1,7 +1,5 @@ -using HotChocolate.Fusion.Errors; using HotChocolate.Fusion.Logging; using HotChocolate.Fusion.PreMergeValidation.Contracts; -using HotChocolate.Fusion.Results; namespace HotChocolate.Fusion.PreMergeValidation.Rules; @@ -12,28 +10,16 @@ namespace HotChocolate.Fusion.PreMergeValidation.Rules; /// /// Specification /// -internal sealed class OutputFieldTypesMergeableRule : IPreMergeValidationRule +internal sealed class OutputFieldTypesMergeableRule + : IEachOutputFieldNameEventHandler { - public CompositionResult Run(PreMergeValidationContext context) + public void OnEachOutputFieldName(EachOutputFieldNameEvent @event) { - var loggingSession = context.Log.CreateSession(); + var (context, fieldName, fieldInfo, typeName) = @event; - foreach (var outputTypeInfo in context.OutputTypeInfo) + if (!ValidationHelper.FieldsAreMergeable([.. fieldInfo.Select(i => i.Field)])) { - foreach (var fieldInfo in outputTypeInfo.FieldInfo) - { - if (!ValidationHelper.FieldsAreMergeable(fieldInfo.Fields)) - { - loggingSession.Write( - LogEntryHelper.OutputFieldTypesNotMergeable( - fieldInfo.FieldName, - outputTypeInfo.TypeName)); - } - } + context.Log.Write(LogEntryHelper.OutputFieldTypesNotMergeable(fieldName, typeName)); } - - return loggingSession.ErrorCount == 0 - ? CompositionResult.Success() - : ErrorHelper.PreMergeValidationRuleFailed(this); } } diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Properties/CompositionResources.Designer.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Properties/CompositionResources.Designer.cs index b3a9cb1b02d..416eba365d5 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Properties/CompositionResources.Designer.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Properties/CompositionResources.Designer.cs @@ -60,11 +60,11 @@ internal CompositionResources() { } /// - /// Looks up a localized string similar to Pre-merge validation rule '{0}' failed. View the composition log for details.. + /// Looks up a localized string similar to Pre-merge validation failed. View the composition log for details.. /// - internal static string ErrorHelper_PreMergeValidationRuleFailed { + internal static string ErrorHelper_PreMergeValidationFailed { get { - return ResourceManager.GetString("ErrorHelper_PreMergeValidationRuleFailed", resourceCulture); + return ResourceManager.GetString("ErrorHelper_PreMergeValidationFailed", resourceCulture); } } diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Properties/CompositionResources.resx b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Properties/CompositionResources.resx index d291d0f232a..6ec14bcc4c0 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Properties/CompositionResources.resx +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Properties/CompositionResources.resx @@ -18,8 +18,8 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - Pre-merge validation rule '{0}' failed. View the composition log for details. + + Pre-merge validation failed. View the composition log for details. The built-in scalar type '{0}' is not accessible. diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SourceSchemaMerger.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SourceSchemaMerger.cs index eb2266bc711..61e5b4658f7 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SourceSchemaMerger.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SourceSchemaMerger.cs @@ -1,5 +1,6 @@ using HotChocolate.Fusion.PostMergeValidation; using HotChocolate.Fusion.PreMergeValidation; +using HotChocolate.Fusion.PreMergeValidation.Rules; using HotChocolate.Fusion.Results; using HotChocolate.Skimmed; @@ -10,7 +11,8 @@ internal sealed class SourceSchemaMerger public CompositionResult Merge(CompositionContext context) { // Pre Merge Validation - var preMergeValidationResult = new PreMergeValidator().Validate(context); + var preMergeValidationResult = + new PreMergeValidator(_preMergeValidationRules).Validate(context); if (preMergeValidationResult.IsFailure) { @@ -41,4 +43,10 @@ private CompositionResult MergeSchemaDefinitions(CompositionCo // FIXME: Implement. return new SchemaDefinition(); } + + private static readonly List _preMergeValidationRules = + [ + new DisallowedInaccessibleElementsRule(), + new OutputFieldTypesMergeableRule() + ]; } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/PreMergeValidation/Rules/DisallowedInaccessibleElementsRuleTests.cs b/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/PreMergeValidation/Rules/DisallowedInaccessibleElementsRuleTests.cs index b46fee89348..3789b4ad1b3 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/PreMergeValidation/Rules/DisallowedInaccessibleElementsRuleTests.cs +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/PreMergeValidation/Rules/DisallowedInaccessibleElementsRuleTests.cs @@ -14,13 +14,11 @@ public async Task Examples_Valid(string[] sdl) { // arrange var log = new CompositionLog(); - var context = new PreMergeValidationContext( - new CompositionContext([.. sdl.Select(SchemaParser.Parse)], log)); - - context.Initialize(); + var context = new CompositionContext([.. sdl.Select(SchemaParser.Parse)], log); + var preMergeValidator = new PreMergeValidator([new DisallowedInaccessibleElementsRule()]); // act - var result = new DisallowedInaccessibleElementsRule().Run(context); + var result = preMergeValidator.Validate(context); // assert await Assert.That(result.IsSuccess).IsTrue(); @@ -33,13 +31,11 @@ public async Task Examples_Invalid(string[] sdl) { // arrange var log = new CompositionLog(); - var context = new PreMergeValidationContext( - new CompositionContext([.. sdl.Select(SchemaParser.Parse)], log)); - - context.Initialize(); + var context = new CompositionContext([.. sdl.Select(SchemaParser.Parse)], log); + var preMergeValidator = new PreMergeValidator([new DisallowedInaccessibleElementsRule()]); // act - var result = new DisallowedInaccessibleElementsRule().Run(context); + var result = preMergeValidator.Validate(context); // assert await Assert.That(result.IsFailure).IsTrue(); diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/PreMergeValidation/Rules/OutputFieldTypesMergeableRuleTests.cs b/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/PreMergeValidation/Rules/OutputFieldTypesMergeableRuleTests.cs index 998ee86ef0d..c87318a0e0a 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/PreMergeValidation/Rules/OutputFieldTypesMergeableRuleTests.cs +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/PreMergeValidation/Rules/OutputFieldTypesMergeableRuleTests.cs @@ -14,13 +14,11 @@ public async Task Examples_Valid(string[] sdl) { // arrange var log = new CompositionLog(); - var context = new PreMergeValidationContext( - new CompositionContext([.. sdl.Select(SchemaParser.Parse)], log)); - - context.Initialize(); + var context = new CompositionContext([.. sdl.Select(SchemaParser.Parse)], log); + var preMergeValidator = new PreMergeValidator([new OutputFieldTypesMergeableRule()]); // act - var result = new OutputFieldTypesMergeableRule().Run(context); + var result = preMergeValidator.Validate(context); // assert await Assert.That(result.IsSuccess).IsTrue(); @@ -33,13 +31,11 @@ public async Task Examples_Invalid(string[] sdl) { // arrange var log = new CompositionLog(); - var context = new PreMergeValidationContext( - new CompositionContext([.. sdl.Select(SchemaParser.Parse)], log)); - - context.Initialize(); + var context = new CompositionContext([.. sdl.Select(SchemaParser.Parse)], log); + var preMergeValidator = new PreMergeValidator([new OutputFieldTypesMergeableRule()]); // act - var result = new OutputFieldTypesMergeableRule().Run(context); + var result = preMergeValidator.Validate(context); // assert await Assert.That(result.IsFailure).IsTrue(); From fac97bdfe22117cd24b3214d8db606a8a7133c62 Mon Sep 17 00:00:00 2001 From: Glen Date: Thu, 12 Dec 2024 13:01:49 +0200 Subject: [PATCH 2/5] Refactored Fusion Composition validation (alternative event handling) --- .../Events/EventAggregator.cs | 29 ----- .../src/Fusion.Composition/Events/IEvent.cs | 3 + .../IEachDirectiveArgumentEventHandler.cs | 6 - .../Contracts/IEachDirectiveEventHandler.cs | 6 - .../IEachFieldArgumentEventHandler.cs | 6 - .../Contracts/IEachOutputFieldEventHandler.cs | 6 - .../IEachOutputFieldNameEventHandler.cs | 6 - .../Contracts/IEachTypeEventHandler.cs | 6 - .../Contracts/IPreMergeValidationRule.cs | 20 ++++ .../PreMergeValidation/Events.cs | 17 +-- .../PreMergeValidationRule.cs | 38 ++++++ .../PreMergeValidation/PreMergeValidator.cs | 113 ++++++++---------- .../DisallowedInaccessibleElementsRule.cs | 15 +-- .../Rules/OutputFieldTypesMergeableRule.cs | 5 +- .../Fusion.Composition/SourceSchemaMerger.cs | 3 +- 15 files changed, 131 insertions(+), 148 deletions(-) delete mode 100644 src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Events/EventAggregator.cs create mode 100644 src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Events/IEvent.cs delete mode 100644 src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachDirectiveArgumentEventHandler.cs delete mode 100644 src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachDirectiveEventHandler.cs delete mode 100644 src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachFieldArgumentEventHandler.cs delete mode 100644 src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachOutputFieldEventHandler.cs delete mode 100644 src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachOutputFieldNameEventHandler.cs delete mode 100644 src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachTypeEventHandler.cs create mode 100644 src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IPreMergeValidationRule.cs create mode 100644 src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/PreMergeValidationRule.cs diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Events/EventAggregator.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Events/EventAggregator.cs deleted file mode 100644 index 496e1c60867..00000000000 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Events/EventAggregator.cs +++ /dev/null @@ -1,29 +0,0 @@ -using HotChocolate.Fusion.Collections; - -namespace HotChocolate.Fusion.Events; - -internal sealed class EventAggregator -{ - private readonly MultiValueDictionary _subscribers = new(); - - public void Subscribe(Action handler) - { - _subscribers.Add(typeof(TEvent), handler); - } - - public void Unsubscribe(Action handler) - { - _subscribers.Remove(typeof(TEvent), handler); - } - - public void Publish(TEvent @event) - { - if (_subscribers.ContainsKey(typeof(TEvent))) - { - foreach (var handler in _subscribers[typeof(TEvent)]) - { - ((Action)handler)(@event); - } - } - } -} diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Events/IEvent.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Events/IEvent.cs new file mode 100644 index 00000000000..fc4b2354184 --- /dev/null +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Events/IEvent.cs @@ -0,0 +1,3 @@ +namespace HotChocolate.Fusion.Events; + +internal interface IEvent; diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachDirectiveArgumentEventHandler.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachDirectiveArgumentEventHandler.cs deleted file mode 100644 index 801352fd4bb..00000000000 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachDirectiveArgumentEventHandler.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace HotChocolate.Fusion.PreMergeValidation.Contracts; - -internal interface IEachDirectiveArgumentEventHandler -{ - void OnEachDirectiveArgument(EachDirectiveArgumentEvent @event); -} diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachDirectiveEventHandler.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachDirectiveEventHandler.cs deleted file mode 100644 index 53cf8f5020c..00000000000 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachDirectiveEventHandler.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace HotChocolate.Fusion.PreMergeValidation.Contracts; - -internal interface IEachDirectiveEventHandler -{ - void OnEachDirective(EachDirectiveEvent @event); -} diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachFieldArgumentEventHandler.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachFieldArgumentEventHandler.cs deleted file mode 100644 index f0d204a1ae3..00000000000 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachFieldArgumentEventHandler.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace HotChocolate.Fusion.PreMergeValidation.Contracts; - -internal interface IEachFieldArgumentEventHandler -{ - void OnEachFieldArgument(EachFieldArgumentEvent @event); -} diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachOutputFieldEventHandler.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachOutputFieldEventHandler.cs deleted file mode 100644 index ecc19bf9f67..00000000000 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachOutputFieldEventHandler.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace HotChocolate.Fusion.PreMergeValidation.Contracts; - -internal interface IEachOutputFieldEventHandler -{ - void OnEachOutputField(EachOutputFieldEvent @event); -} diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachOutputFieldNameEventHandler.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachOutputFieldNameEventHandler.cs deleted file mode 100644 index 96d74460032..00000000000 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachOutputFieldNameEventHandler.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace HotChocolate.Fusion.PreMergeValidation.Contracts; - -internal interface IEachOutputFieldNameEventHandler -{ - void OnEachOutputFieldName(EachOutputFieldNameEvent @event); -} diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachTypeEventHandler.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachTypeEventHandler.cs deleted file mode 100644 index 071d939ad13..00000000000 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IEachTypeEventHandler.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace HotChocolate.Fusion.PreMergeValidation.Contracts; - -internal interface IEachTypeEventHandler -{ - void OnEachType(EachTypeEvent @event); -} diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IPreMergeValidationRule.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IPreMergeValidationRule.cs new file mode 100644 index 00000000000..f0d5b4eccce --- /dev/null +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IPreMergeValidationRule.cs @@ -0,0 +1,20 @@ +namespace HotChocolate.Fusion.PreMergeValidation.Contracts; + +internal interface IPreMergeValidationRule +{ + void OnEachType(EachTypeEvent @event); + + void OnEachOutputField(EachOutputFieldEvent @event); + + void OnEachFieldArgument(EachFieldArgumentEvent @event); + + void OnEachDirective(EachDirectiveEvent @event); + + void OnEachDirectiveArgument(EachDirectiveArgumentEvent @event); + + void OnEachTypeName(EachTypeNameEvent @event); + + void OnEachOutputFieldName(EachOutputFieldNameEvent @event); + + void OnEachFieldArgumentName(EachFieldArgumentNameEvent @event); +} diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Events.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Events.cs index fd2978f5411..cc3c7d75a83 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Events.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Events.cs @@ -1,4 +1,5 @@ using System.Collections.Immutable; +using HotChocolate.Fusion.Events; using HotChocolate.Skimmed; namespace HotChocolate.Fusion.PreMergeValidation; @@ -7,45 +8,45 @@ internal record EachDirectiveArgumentEvent( CompositionContext Context, InputFieldDefinition Argument, DirectiveDefinition Directive, - SchemaDefinition Schema); + SchemaDefinition Schema) : IEvent; internal record EachDirectiveEvent( CompositionContext Context, DirectiveDefinition Directive, - SchemaDefinition Schema); + SchemaDefinition Schema) : IEvent; internal record EachFieldArgumentEvent( CompositionContext Context, InputFieldDefinition Argument, OutputFieldDefinition Field, INamedTypeDefinition Type, - SchemaDefinition Schema); + SchemaDefinition Schema) : IEvent; internal record EachFieldArgumentNameEvent( CompositionContext Context, string ArgumentName, ImmutableArray ArgumentInfo, string FieldName, - string TypeName); + string TypeName) : IEvent; internal record EachOutputFieldEvent( CompositionContext Context, OutputFieldDefinition Field, INamedTypeDefinition Type, - SchemaDefinition Schema); + SchemaDefinition Schema) : IEvent; internal record EachOutputFieldNameEvent( CompositionContext Context, string FieldName, ImmutableArray FieldInfo, - string TypeName); + string TypeName) : IEvent; internal record EachTypeEvent( CompositionContext Context, INamedTypeDefinition Type, - SchemaDefinition Schema); + SchemaDefinition Schema) : IEvent; internal record EachTypeNameEvent( CompositionContext Context, string TypeName, - ImmutableArray TypeInfo); + ImmutableArray TypeInfo) : IEvent; diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/PreMergeValidationRule.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/PreMergeValidationRule.cs new file mode 100644 index 00000000000..884be8b998b --- /dev/null +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/PreMergeValidationRule.cs @@ -0,0 +1,38 @@ +using HotChocolate.Fusion.PreMergeValidation.Contracts; + +namespace HotChocolate.Fusion.PreMergeValidation; + +internal abstract class PreMergeValidationRule : IPreMergeValidationRule +{ + public virtual void OnEachType(EachTypeEvent @event) + { + } + + public virtual void OnEachOutputField(EachOutputFieldEvent @event) + { + } + + public virtual void OnEachFieldArgument(EachFieldArgumentEvent @event) + { + } + + public virtual void OnEachDirective(EachDirectiveEvent @event) + { + } + + public virtual void OnEachDirectiveArgument(EachDirectiveArgumentEvent @event) + { + } + + public virtual void OnEachTypeName(EachTypeNameEvent @event) + { + } + + public virtual void OnEachOutputFieldName(EachOutputFieldNameEvent @event) + { + } + + public virtual void OnEachFieldArgumentName(EachFieldArgumentNameEvent @event) + { + } +} diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/PreMergeValidator.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/PreMergeValidator.cs index 8c949f815a2..60a03b919bb 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/PreMergeValidator.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/PreMergeValidator.cs @@ -1,3 +1,4 @@ +using System.Collections.Immutable; using HotChocolate.Fusion.Collections; using HotChocolate.Fusion.Errors; using HotChocolate.Fusion.Events; @@ -7,16 +8,9 @@ namespace HotChocolate.Fusion.PreMergeValidation; -internal sealed class PreMergeValidator +internal sealed class PreMergeValidator(IEnumerable rules) { - private readonly EventAggregator _eventAggregator; - - public PreMergeValidator(IEnumerable rules) - { - _eventAggregator = new EventAggregator(); - - SubscribeRules(rules); - } + private readonly ImmutableArray _rules = [.. rules]; public CompositionResult Validate(CompositionContext context) { @@ -27,48 +21,6 @@ public CompositionResult Validate(CompositionContext context) : CompositionResult.Success(); } - private void SubscribeRules(IEnumerable rules) - { - foreach (var rule in rules) - { - if (rule is IEachTypeEventHandler eachTypeEventHandler) - { - _eventAggregator.Subscribe( - eachTypeEventHandler.OnEachType); - } - - if (rule is IEachOutputFieldEventHandler eachOutputFieldEventHandler) - { - _eventAggregator.Subscribe( - eachOutputFieldEventHandler.OnEachOutputField); - } - - if (rule is IEachFieldArgumentEventHandler eachFieldArgumentEventHandler) - { - _eventAggregator.Subscribe( - eachFieldArgumentEventHandler.OnEachFieldArgument); - } - - if (rule is IEachDirectiveEventHandler eachDirectiveEventHandler) - { - _eventAggregator.Subscribe( - eachDirectiveEventHandler.OnEachDirective); - } - - if (rule is IEachDirectiveArgumentEventHandler eachDirectiveArgumentEventHandler) - { - _eventAggregator.Subscribe( - eachDirectiveArgumentEventHandler.OnEachDirectiveArgument); - } - - if (rule is IEachOutputFieldNameEventHandler eachOutputFieldNameEventHandler) - { - _eventAggregator.Subscribe( - eachOutputFieldNameEventHandler.OnEachOutputFieldName); - } - } - } - private void PublishEvents(CompositionContext context) { MultiValueDictionary typeInfoByName = []; @@ -77,7 +29,7 @@ private void PublishEvents(CompositionContext context) { foreach (var type in schema.Types) { - _eventAggregator.Publish(new EachTypeEvent(context, type, schema)); + PublishEvent(new EachTypeEvent(context, type, schema)); typeInfoByName.Add(type.Name, new TypeInfo(type, schema)); @@ -85,12 +37,11 @@ private void PublishEvents(CompositionContext context) { foreach (var field in complexType.Fields) { - _eventAggregator.Publish( - new EachOutputFieldEvent(context, field, type, schema)); + PublishEvent(new EachOutputFieldEvent(context, field, type, schema)); foreach (var argument in field.Arguments) { - _eventAggregator.Publish( + PublishEvent( new EachFieldArgumentEvent(context, argument, field, type, schema)); } } @@ -99,12 +50,11 @@ private void PublishEvents(CompositionContext context) foreach (var directive in schema.DirectiveDefinitions) { - _eventAggregator.Publish( - new EachDirectiveEvent(context, directive, schema)); + PublishEvent(new EachDirectiveEvent(context, directive, schema)); foreach (var argument in directive.Arguments) { - _eventAggregator.Publish( + PublishEvent( new EachDirectiveArgumentEvent(context, argument, directive, schema)); } } @@ -112,7 +62,7 @@ private void PublishEvents(CompositionContext context) foreach (var (typeName, typeInfo) in typeInfoByName) { - _eventAggregator.Publish(new EachTypeNameEvent(context, typeName, [.. typeInfo])); + PublishEvent(new EachTypeNameEvent(context, typeName, [.. typeInfo])); MultiValueDictionary fieldInfoByName = []; @@ -129,7 +79,7 @@ private void PublishEvents(CompositionContext context) foreach (var (fieldName, fieldInfo) in fieldInfoByName) { - _eventAggregator.Publish( + PublishEvent( new EachOutputFieldNameEvent(context, fieldName, [.. fieldInfo], typeName)); MultiValueDictionary argumentInfoByName = []; @@ -146,7 +96,7 @@ private void PublishEvents(CompositionContext context) foreach (var (argumentName, argumentInfo) in argumentInfoByName) { - _eventAggregator.Publish( + PublishEvent( new EachFieldArgumentNameEvent( context, argumentName, @@ -157,6 +107,47 @@ private void PublishEvents(CompositionContext context) } } } + + private void PublishEvent(IEvent @event) + { + foreach (var rule in _rules) + { + switch (@event) + { + case EachTypeEvent e: + rule.OnEachType(e); + break; + + case EachOutputFieldEvent e: + rule.OnEachOutputField(e); + break; + + case EachFieldArgumentEvent e: + rule.OnEachFieldArgument(e); + break; + + case EachDirectiveEvent e: + rule.OnEachDirective(e); + break; + + case EachDirectiveArgumentEvent e: + rule.OnEachDirectiveArgument(e); + break; + + case EachTypeNameEvent e: + rule.OnEachTypeName(e); + break; + + case EachOutputFieldNameEvent e: + rule.OnEachOutputFieldName(e); + break; + + case EachFieldArgumentNameEvent e: + rule.OnEachFieldArgumentName(e); + break; + } + } + } } internal record TypeInfo( diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Rules/DisallowedInaccessibleElementsRule.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Rules/DisallowedInaccessibleElementsRule.cs index 95fb7e5df79..3421ec08e66 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Rules/DisallowedInaccessibleElementsRule.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Rules/DisallowedInaccessibleElementsRule.cs @@ -1,4 +1,3 @@ -using HotChocolate.Fusion.PreMergeValidation.Contracts; using HotChocolate.Skimmed; using static HotChocolate.Fusion.Logging.LogEntryHelper; @@ -13,13 +12,9 @@ namespace HotChocolate.Fusion.PreMergeValidation.Rules; /// /// Specification /// -internal sealed class DisallowedInaccessibleElementsRule - : IEachTypeEventHandler - , IEachOutputFieldEventHandler - , IEachFieldArgumentEventHandler - , IEachDirectiveArgumentEventHandler +internal sealed class DisallowedInaccessibleElementsRule : PreMergeValidationRule { - public void OnEachType(EachTypeEvent @event) + public override void OnEachType(EachTypeEvent @event) { var (context, type, schema) = @event; @@ -37,7 +32,7 @@ public void OnEachType(EachTypeEvent @event) } } - public void OnEachOutputField(EachOutputFieldEvent @event) + public override void OnEachOutputField(EachOutputFieldEvent @event) { var (context, field, type, schema) = @event; @@ -52,7 +47,7 @@ public void OnEachOutputField(EachOutputFieldEvent @event) } } - public void OnEachFieldArgument(EachFieldArgumentEvent @event) + public override void OnEachFieldArgument(EachFieldArgumentEvent @event) { var (context, argument, field, type, schema) = @event; @@ -68,7 +63,7 @@ public void OnEachFieldArgument(EachFieldArgumentEvent @event) } } - public void OnEachDirectiveArgument(EachDirectiveArgumentEvent @event) + public override void OnEachDirectiveArgument(EachDirectiveArgumentEvent @event) { var (context, argument, directive, schema) = @event; diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Rules/OutputFieldTypesMergeableRule.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Rules/OutputFieldTypesMergeableRule.cs index 5cec7b28ba6..9ee1f80244e 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Rules/OutputFieldTypesMergeableRule.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Rules/OutputFieldTypesMergeableRule.cs @@ -10,10 +10,9 @@ namespace HotChocolate.Fusion.PreMergeValidation.Rules; /// /// Specification /// -internal sealed class OutputFieldTypesMergeableRule - : IEachOutputFieldNameEventHandler +internal sealed class OutputFieldTypesMergeableRule : PreMergeValidationRule { - public void OnEachOutputFieldName(EachOutputFieldNameEvent @event) + public override void OnEachOutputFieldName(EachOutputFieldNameEvent @event) { var (context, fieldName, fieldInfo, typeName) = @event; diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SourceSchemaMerger.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SourceSchemaMerger.cs index 61e5b4658f7..3947119100c 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SourceSchemaMerger.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SourceSchemaMerger.cs @@ -1,5 +1,6 @@ using HotChocolate.Fusion.PostMergeValidation; using HotChocolate.Fusion.PreMergeValidation; +using HotChocolate.Fusion.PreMergeValidation.Contracts; using HotChocolate.Fusion.PreMergeValidation.Rules; using HotChocolate.Fusion.Results; using HotChocolate.Skimmed; @@ -44,7 +45,7 @@ private CompositionResult MergeSchemaDefinitions(CompositionCo return new SchemaDefinition(); } - private static readonly List _preMergeValidationRules = + private static readonly List _preMergeValidationRules = [ new DisallowedInaccessibleElementsRule(), new OutputFieldTypesMergeableRule() From 3b429cdae0fd821c2add8eed615585054e727149 Mon Sep 17 00:00:00 2001 From: Glen Date: Thu, 12 Dec 2024 15:07:14 +0200 Subject: [PATCH 3/5] Renamed EachTypeNameEvent to EachTypeGroupEvent, etc. --- .../Contracts/IPreMergeValidationRule.cs | 6 +-- .../PreMergeValidation/Events.cs | 12 +++--- .../PreMergeValidationRule.cs | 6 +-- .../PreMergeValidation/PreMergeValidator.cs | 42 +++++++++---------- .../Rules/OutputFieldTypesMergeableRule.cs | 6 +-- 5 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IPreMergeValidationRule.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IPreMergeValidationRule.cs index f0d5b4eccce..377ce5c358d 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IPreMergeValidationRule.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Contracts/IPreMergeValidationRule.cs @@ -12,9 +12,9 @@ internal interface IPreMergeValidationRule void OnEachDirectiveArgument(EachDirectiveArgumentEvent @event); - void OnEachTypeName(EachTypeNameEvent @event); + void OnEachTypeGroup(EachTypeGroupEvent @event); - void OnEachOutputFieldName(EachOutputFieldNameEvent @event); + void OnEachOutputFieldGroup(EachOutputFieldGroupEvent @event); - void OnEachFieldArgumentName(EachFieldArgumentNameEvent @event); + void OnEachFieldArgumentGroup(EachFieldArgumentGroupEvent @event); } diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Events.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Events.cs index cc3c7d75a83..c50e73cd381 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Events.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Events.cs @@ -22,10 +22,10 @@ internal record EachFieldArgumentEvent( INamedTypeDefinition Type, SchemaDefinition Schema) : IEvent; -internal record EachFieldArgumentNameEvent( +internal record EachFieldArgumentGroupEvent( CompositionContext Context, string ArgumentName, - ImmutableArray ArgumentInfo, + ImmutableArray ArgumentGroup, string FieldName, string TypeName) : IEvent; @@ -35,10 +35,10 @@ internal record EachOutputFieldEvent( INamedTypeDefinition Type, SchemaDefinition Schema) : IEvent; -internal record EachOutputFieldNameEvent( +internal record EachOutputFieldGroupEvent( CompositionContext Context, string FieldName, - ImmutableArray FieldInfo, + ImmutableArray FieldGroup, string TypeName) : IEvent; internal record EachTypeEvent( @@ -46,7 +46,7 @@ internal record EachTypeEvent( INamedTypeDefinition Type, SchemaDefinition Schema) : IEvent; -internal record EachTypeNameEvent( +internal record EachTypeGroupEvent( CompositionContext Context, string TypeName, - ImmutableArray TypeInfo) : IEvent; + ImmutableArray TypeGroup) : IEvent; diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/PreMergeValidationRule.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/PreMergeValidationRule.cs index 884be8b998b..ad73e69bf85 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/PreMergeValidationRule.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/PreMergeValidationRule.cs @@ -24,15 +24,15 @@ public virtual void OnEachDirectiveArgument(EachDirectiveArgumentEvent @event) { } - public virtual void OnEachTypeName(EachTypeNameEvent @event) + public virtual void OnEachTypeGroup(EachTypeGroupEvent @event) { } - public virtual void OnEachOutputFieldName(EachOutputFieldNameEvent @event) + public virtual void OnEachOutputFieldGroup(EachOutputFieldGroupEvent @event) { } - public virtual void OnEachFieldArgumentName(EachFieldArgumentNameEvent @event) + public virtual void OnEachFieldArgumentGroup(EachFieldArgumentGroupEvent @event) { } } diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/PreMergeValidator.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/PreMergeValidator.cs index 60a03b919bb..163d6c8e523 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/PreMergeValidator.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/PreMergeValidator.cs @@ -23,7 +23,7 @@ public CompositionResult Validate(CompositionContext context) private void PublishEvents(CompositionContext context) { - MultiValueDictionary typeInfoByName = []; + MultiValueDictionary typeGroupByName = []; foreach (var schema in context.SchemaDefinitions) { @@ -31,7 +31,7 @@ private void PublishEvents(CompositionContext context) { PublishEvent(new EachTypeEvent(context, type, schema)); - typeInfoByName.Add(type.Name, new TypeInfo(type, schema)); + typeGroupByName.Add(type.Name, new TypeInfo(type, schema)); if (type is ComplexTypeDefinition complexType) { @@ -60,47 +60,47 @@ private void PublishEvents(CompositionContext context) } } - foreach (var (typeName, typeInfo) in typeInfoByName) + foreach (var (typeName, typeGroup) in typeGroupByName) { - PublishEvent(new EachTypeNameEvent(context, typeName, [.. typeInfo])); + PublishEvent(new EachTypeGroupEvent(context, typeName, [.. typeGroup])); - MultiValueDictionary fieldInfoByName = []; + MultiValueDictionary fieldGroupByName = []; - foreach (var (type, schema) in typeInfo) + foreach (var (type, schema) in typeGroup) { if (type is ComplexTypeDefinition complexType) { foreach (var field in complexType.Fields) { - fieldInfoByName.Add(field.Name, new OutputFieldInfo(field, type, schema)); + fieldGroupByName.Add(field.Name, new OutputFieldInfo(field, type, schema)); } } } - foreach (var (fieldName, fieldInfo) in fieldInfoByName) + foreach (var (fieldName, fieldGroup) in fieldGroupByName) { PublishEvent( - new EachOutputFieldNameEvent(context, fieldName, [.. fieldInfo], typeName)); + new EachOutputFieldGroupEvent(context, fieldName, [.. fieldGroup], typeName)); - MultiValueDictionary argumentInfoByName = []; + MultiValueDictionary argumentGroupByName = []; - foreach (var (field, type, schema) in fieldInfo) + foreach (var (field, type, schema) in fieldGroup) { foreach (var argument in field.Arguments) { - argumentInfoByName.Add( + argumentGroupByName.Add( argument.Name, new FieldArgumentInfo(argument, field, type, schema)); } } - foreach (var (argumentName, argumentInfo) in argumentInfoByName) + foreach (var (argumentName, argumentGroup) in argumentGroupByName) { PublishEvent( - new EachFieldArgumentNameEvent( + new EachFieldArgumentGroupEvent( context, argumentName, - [.. argumentInfo], + [.. argumentGroup], fieldName, typeName)); } @@ -134,16 +134,16 @@ private void PublishEvent(IEvent @event) rule.OnEachDirectiveArgument(e); break; - case EachTypeNameEvent e: - rule.OnEachTypeName(e); + case EachTypeGroupEvent e: + rule.OnEachTypeGroup(e); break; - case EachOutputFieldNameEvent e: - rule.OnEachOutputFieldName(e); + case EachOutputFieldGroupEvent e: + rule.OnEachOutputFieldGroup(e); break; - case EachFieldArgumentNameEvent e: - rule.OnEachFieldArgumentName(e); + case EachFieldArgumentGroupEvent e: + rule.OnEachFieldArgumentGroup(e); break; } } diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Rules/OutputFieldTypesMergeableRule.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Rules/OutputFieldTypesMergeableRule.cs index 9ee1f80244e..d1ac09ddb58 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Rules/OutputFieldTypesMergeableRule.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Rules/OutputFieldTypesMergeableRule.cs @@ -12,11 +12,11 @@ namespace HotChocolate.Fusion.PreMergeValidation.Rules; /// internal sealed class OutputFieldTypesMergeableRule : PreMergeValidationRule { - public override void OnEachOutputFieldName(EachOutputFieldNameEvent @event) + public override void OnEachOutputFieldGroup(EachOutputFieldGroupEvent @event) { - var (context, fieldName, fieldInfo, typeName) = @event; + var (context, fieldName, fieldGroup, typeName) = @event; - if (!ValidationHelper.FieldsAreMergeable([.. fieldInfo.Select(i => i.Field)])) + if (!ValidationHelper.FieldsAreMergeable([.. fieldGroup.Select(i => i.Field)])) { context.Log.Write(LogEntryHelper.OutputFieldTypesNotMergeable(fieldName, typeName)); } From fbbdc39e221d317fd090198b77fc18e59fd7a947 Mon Sep 17 00:00:00 2001 From: Glen Date: Thu, 12 Dec 2024 15:08:35 +0200 Subject: [PATCH 4/5] Removed unused using directive --- .../PreMergeValidation/Rules/OutputFieldTypesMergeableRule.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Rules/OutputFieldTypesMergeableRule.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Rules/OutputFieldTypesMergeableRule.cs index d1ac09ddb58..cb111bc86a9 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Rules/OutputFieldTypesMergeableRule.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidation/Rules/OutputFieldTypesMergeableRule.cs @@ -1,5 +1,4 @@ using HotChocolate.Fusion.Logging; -using HotChocolate.Fusion.PreMergeValidation.Contracts; namespace HotChocolate.Fusion.PreMergeValidation.Rules; From 0984abfeca47ca6d4355cd54fe86137deab95546 Mon Sep 17 00:00:00 2001 From: Glen Date: Thu, 12 Dec 2024 15:09:23 +0200 Subject: [PATCH 5/5] Used List instead of IList in MultiValueDictionary --- .../src/Fusion.Composition/Collections/MultiValueDictionary.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Collections/MultiValueDictionary.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Collections/MultiValueDictionary.cs index 94f49f1c3bd..1be86756585 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Collections/MultiValueDictionary.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Collections/MultiValueDictionary.cs @@ -1,7 +1,7 @@ namespace HotChocolate.Fusion.Collections; internal sealed class MultiValueDictionary - : Dictionary> where TKey : notnull + : Dictionary> where TKey : notnull { public void Add(TKey key, TValue value) {