Simplify rabbitmq explicit binding#9911
Open
PascalSenn wants to merge 8 commits into
Open
Conversation
PascalSenn
commented
Jun 14, 2026
Member
- rework explicity binding of rabbitmq
- Add bus interceptor functionality to IMessageBusBuilder and related classes
Contributor
There was a problem hiding this comment.
Pull request overview
This PR refactors transport routing/binding to better support explicit binding (especially for RabbitMQ), adds transport selection controls for outbound routes (OnTransport, default transport validation), and introduces a bus interceptor registration API intended to hook into topology finalization.
Changes:
- Added transport-selection metadata to outbound routes (
TransportName,HasExplicitDestination) plus build-time validation for default transport andOnTransportinvariants. - Introduced queue-/type-level auto-bind and explicit bind intents (
AutoBind,BindFrom) and materialized these intents during receive topology discovery across RabbitMQ/Postgres/InMemory. - Added snapshot-based topology assertions and expanded test coverage across transports (including “unified queue” front door behavior and publish endpoint overrides).
Reviewed changes
Copilot reviewed 198 out of 198 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Mocha/src/Mocha/Builder/MessageBusBuilder.cs | Builds interceptor list feature; adds transport configuration validation. |
| src/Mocha/src/Mocha/Builder/MessageBusBuilder.Interceptors.cs | Adds AddBusInterceptor registration APIs and interceptor ordering logic. |
| src/Mocha/src/Mocha/Abstractions/IMessageBusBuilder.cs | Exposes bus interceptor registration API on the builder abstraction. |
| src/Mocha/src/Mocha/Interceptors/BusInterceptor.cs | Defines interceptor hooks for topology lifecycle. |
| src/Mocha/src/Mocha/Interceptors/BusInterceptorFeature.cs | Stores resolved interceptor list as a bus feature. |
| src/Mocha/src/Mocha/Interceptors/BusInterceptorRegistration.cs | Internal model for interceptor registrations. |
| src/Mocha/src/Mocha/Interceptors/IBusInterceptorTopologyContext.cs | Context interface for interceptor topology hooks. |
| src/Mocha/src/Mocha/Middlewares/DefaultMessageBus.cs | Adds PublishOptions.Endpoint override routing to dispatch endpoint. |
| src/Mocha/src/Mocha/Execution/PublishOptions.cs | Adds Endpoint property for publish override. |
| src/Mocha/src/Mocha/MessageTypes/OutboundRoute.cs | Adds HasExplicitDestination + TransportName tracking. |
| src/Mocha/src/Mocha/MessageTypes/IMessageRouter.cs | Switches outbound transport selection to MessagingTransportSelection. |
| src/Mocha/src/Mocha/MessageTypes/Descriptors/IOutboundRouteDescriptor.cs | Adds OnTransport(string) API. |
| src/Mocha/src/Mocha/MessageTypes/Descriptors/OutboundRouteDescriptor.cs | Implements OnTransport(string) storing transport override. |
| src/Mocha/src/Mocha/MessageTypes/Configurations/OutboundRouteConfiguration.cs | Stores TransportName on route configuration. |
| src/Mocha/src/Mocha/MessageTypes/Extensions/OutboundRouteDescriptorExtensions.cs | Documents neutral-scheme addressing constraints in multi-transport setups. |
| src/Mocha/src/Mocha/Transport/MessagingTransportDescriptor.cs | Adds transport-scope AutoBind(bool) to descriptor. |
| src/Mocha/src/Mocha/Transport/MessagingTransportConfiguration.cs | Adds tri-state AutoBind and expands default transport documentation. |
| src/Mocha/src/Mocha/Transport/MessagingTransport.cs | Exposes ConsumerBindingMode, AutoBind, IsDefaultTransport on transports. |
| src/Mocha/src/Mocha/Consumers/ConsumerBindingMode.cs | Reorders binding mode enum (now implicit-first). |
| src/Mocha/src/Mocha/Endpoints/ReceiveEndpoint.cs | Adds OnDiscoverTopology hook prior to convention discovery. |
| src/Mocha/src/Mocha/Endpoints/ReceiveEndpoint~1.cs | Plumbs typed OnDiscoverTopology into generic endpoint base. |
| src/Mocha/src/Mocha/Endpoints/ReceiveTypeBindIntent.cs | Adds intent models for per-type and bind-from declarations. |
| src/Mocha/src/Mocha/Endpoints/Configurations/ReceiveEndpointConfiguration.cs | Adds queue-scope AutoBind, per-type binds, and queue-level bind-from intents. |
| src/Mocha/src/Mocha/Endpoints/Descriptors/IReceiveEndpointDescriptor.cs | Adds Receives<T>(configure), AutoBind, and BindFrom APIs. |
| src/Mocha/src/Mocha/Endpoints/Descriptors/IReceiveTypeBindDescriptor.cs | Adds per-type auto-bind and bind-from fluent API. |
| src/Mocha/src/Mocha/Endpoints/Descriptors/ReceiveEndpointDescriptor.cs | Implements per-type configure overload and merges type bind intents. |
| src/Mocha/src/Mocha/Endpoints/Descriptors/ReceiveTypeBindDescriptor.cs | Collects per-type bind intents and resolves implicit vs explicit AutoBind. |
| src/Mocha/src/Mocha/Sagas/SagaTransition.cs | Removes transition AutoProvision state. |
| src/Mocha/src/Mocha/Sagas/Saga.Initialization.cs | Updates saga transition initialization accordingly. |
| src/Mocha/src/Mocha/Sagas/Saga.cs | Removes AutoProvision from saga descriptions. |
| src/Mocha/src/Mocha/Sagas/Descriptors/ISagaTransitionDescriptor.cs | Removes AutoProvision(...) from saga transition descriptor API. |
| src/Mocha/src/Mocha/Sagas/Descriptors/SagaTransitionDescriptor.cs | Removes AutoProvision(...) implementation. |
| src/Mocha/src/Mocha/Sagas/Definitions/SagaTransitionConfiguration.cs | Removes AutoProvision from transition configuration. |
| src/Mocha/src/Mocha/Descriptions/SagaTransitionDescription.cs | Removes AutoProvision from transition description record. |
| src/Mocha/src/Mocha.Transport.RabbitMQ/RabbitMQReceiveEndpoint.cs | Materializes queue and bind-from intents into RabbitMQ topology. |
| src/Mocha/src/Mocha.Transport.RabbitMQ/Conventions/RabbitMQDefaultReceiveEndpointConvention.cs | Builds typed satellite endpoints (verbatim names, disable flags, auto-provision inheritance). |
| src/Mocha/src/Mocha.Transport.RabbitMQ/Configurations/RabbitMQReceiveEndpointConfiguration.cs | Adds typed satellite config and queue-specific durable/args/autoprovision fields. |
| src/Mocha/src/Mocha.Transport.RabbitMQ/Configurations/RabbitMQSatelliteConfiguration.cs | Adds typed satellite configuration model (name/disable/autoprovision). |
| src/Mocha/src/Mocha.Transport.RabbitMQ/Configurations/RabbitMQDispatchEndpointConfiguration.cs | Adds dispatch-queue auto-provision override. |
| src/Mocha/src/Mocha.Transport.RabbitMQ/Topology/RabbitMQTopologyShapeConflictException.cs | Adds explicit exception for conflicting declared vs convention shapes. |
| src/Mocha/src/Mocha.Transport.RabbitMQ/Topology/RabbitMQTopologyProvenance.cs | Adds provenance constants for declared/convention/endpoint topology nodes. |
| src/Mocha/src/Mocha.Transport.RabbitMQ/Topology/Descriptors/RabbitMQQueueDescriptor.cs | Marks declared queue provenance on descriptor-created queues. |
| src/Mocha/src/Mocha.Transport.RabbitMQ/Topology/Descriptors/RabbitMQExchangeDescriptor.cs | Marks declared exchange provenance on descriptor-created exchanges. |
| src/Mocha/src/Mocha.Transport.RabbitMQ/Topology/Descriptors/RabbitMQBindingDescriptor.cs | Marks declared binding provenance on descriptor-created bindings. |
| src/Mocha/src/Mocha.Transport.RabbitMQ/Topology/Descriptors/IRabbitMQExchangeContributionDescriptor.cs | Adds interface for partial exchange contribution (publish/send). |
| src/Mocha/src/Mocha.Transport.RabbitMQ/Topology/Configurations/RabbitMQQueueConfiguration.cs | Adds provenance metadata to queue config. |
| src/Mocha/src/Mocha.Transport.RabbitMQ/Topology/Configurations/RabbitMQExchangeConfiguration.cs | Adds provenance metadata defaulting to convention. |
| src/Mocha/src/Mocha.Transport.RabbitMQ/Topology/Configurations/RabbitMQBindingConfiguration.cs | Adds provenance metadata defaulting to convention. |
| src/Mocha/src/Mocha.Transport.RabbitMQ/RabbitMQPublishExchangeFeature.cs | Stores publish-exchange partial declaration as a feature. |
| src/Mocha/src/Mocha.Transport.RabbitMQ/RabbitMQSendExchangeFeature.cs | Stores send-exchange partial declaration as a feature. |
| src/Mocha/src/Mocha.Transport.RabbitMQ/RabbitMQMessageTypeExtensions.cs | Adds PublishExchange/SendExchange message type extensions. |
| src/Mocha/src/Mocha.Transport.RabbitMQ/Descriptors/IRabbitMQReceiveEndpointDescriptor.cs | Adds typed satellites + bind/auto-bind APIs to RabbitMQ receive descriptors. |
| src/Mocha/src/Mocha.Transport.RabbitMQ/Descriptors/IRabbitMQMessagingTransportDescriptor.cs | Adds AutoBind and unified Queue(...) front door APIs. |
| src/Mocha/src/Mocha.Transport.Postgres/PostgresMessagingTransport.cs | Uses destination resolver for endpoint configuration + neutral scheme claiming rules. |
| src/Mocha/src/Mocha.Transport.Postgres/PostgresReceiveEndpoint.cs | Materializes queue/topic + bind-from intents into Postgres topology. |
| src/Mocha/src/Mocha.Transport.Postgres/Conventions/PostgresDispatchEndpointTopologyConvention.cs | Ensures bridge topics in implicit mode via resolver. |
| src/Mocha/src/Mocha.Transport.Postgres/Conventions/PostgresDefaultReceiveEndpointConvention.cs | Adds typed satellite naming/disable behavior. |
| src/Mocha/src/Mocha.Transport.Postgres/Configurations/PostgresReceiveEndpointConfiguration.cs | Adds typed satellite configuration to receive endpoints. |
| src/Mocha/src/Mocha.Transport.Postgres/Configurations/PostgresSatelliteConfiguration.cs | Adds typed satellite config model (name/disable). |
| src/Mocha/src/Mocha.Transport.Postgres/Topology/PostgresMessagingTopology.cs | Allows merging queue/topic duplicates (strengthening AutoProvision). |
| src/Mocha/src/Mocha.Transport.Postgres/Topology/PostgresQueue.cs | Adds merge behavior for queue provisioning settings. |
| src/Mocha/src/Mocha.Transport.Postgres/Topology/PostgresTopic.cs | Adds merge behavior for topic provisioning settings. |
| src/Mocha/src/Mocha.Transport.Postgres/Descriptors/IPostgresReceiveEndpointDescriptor.cs | Adds typed satellites + bind/auto-bind APIs to Postgres receive descriptors. |
| src/Mocha/src/Mocha.Transport.Postgres/Descriptors/IPostgresMessagingTransportDescriptor.cs | Adds AutoBind and unified Queue(...) front door APIs. |
| src/Mocha/src/Mocha.Transport.Postgres/Descriptors/IPostgresQueueEndpointDescriptor.cs | Adds unified queue endpoint descriptor (pinned identity). |
| src/Mocha/src/Mocha.Transport.InMemory/InMemoryMessagingTransport.cs | Uses destination resolver for endpoint configuration + neutral scheme claiming rules. |
| src/Mocha/src/Mocha.Transport.InMemory/InMemoryReceiveEndpoint.cs | Materializes queue/topic + bind-from intents into in-memory topology. |
| src/Mocha/src/Mocha.Transport.InMemory/Topology/InMemoryMessagingTopology.cs | Returns existing queue/topic on duplicates instead of throwing. |
| src/Mocha/src/Mocha.Transport.InMemory/Descriptors/InMemoryReceiveEndpointDescriptor.cs | Adds queue identity pinning and bind/auto-bind APIs. |
| src/Mocha/src/Mocha.Transport.InMemory/Descriptors/IInMemoryReceiveEndpointDescriptor.cs | Adds bind/auto-bind APIs to in-memory receive descriptor interface. |
| src/Mocha/src/Mocha.Transport.InMemory/Descriptors/IInMemoryMessagingTransportDescriptor.cs | Adds AutoBind and unified Queue(...) front door APIs. |
| src/Mocha/src/Mocha.Transport.InMemory/Descriptors/IInMemoryQueueEndpointDescriptor.cs | Adds unified queue endpoint descriptor (pinned identity). |
| src/Mocha/test/Mocha.Transport.RabbitMQ.Tests/Mocha.Transport.RabbitMQ.Tests.csproj | Adds CookieCrumble snapshot test project references/analyzers. |
| src/Mocha/test/Mocha.Transport.RabbitMQ.Tests/Helpers/RabbitMQDescribeSnapshot.cs | Adds deterministic JSON projection for RabbitMQ topology snapshots. |
| src/Mocha/test/Mocha.Transport.RabbitMQ.Tests/RabbitMQReceiveEndpointTests.cs | Updates tests to typed satellites (ErrorQueue/SkippedQueue). |
| src/Mocha/test/Mocha.Transport.RabbitMQ.Tests/Descriptors/RabbitMQHandlerBindingTests.cs | Adds CookieCrumble snapshot assertions for binding modes and auto-bind behavior. |
| src/Mocha/test/Mocha.Transport.RabbitMQ.Tests/Descriptors/RabbitMQQueueFrontDoorTests.cs | Adds unified Queue(...) endpoint convergence tests. |
| src/Mocha/test/Mocha.Transport.RabbitMQ.Tests/Routing/RabbitMQTransportResolverWiringTests.cs | Adds wiring tests for resolver-based dispatch endpoint configuration. |
| src/Mocha/test/Mocha.Transport.RabbitMQ.Tests/**/snapshots/*.snap | Adds/updates many RabbitMQ topology snapshots reflecting new discovery/merge behavior. |
| src/Mocha/test/Mocha.Transport.Postgres.Tests/Helpers/PostgresDescribeSnapshot.cs | Adds deterministic JSON projection for Postgres topology snapshots. |
| src/Mocha/test/Mocha.Transport.Postgres.Tests/PostgresSatelliteTests.cs | Adds typed satellite behavior snapshots for Postgres. |
| src/Mocha/test/Mocha.Transport.Postgres.Tests/PostgresReceiveEndpointBindFromTests.cs | Adds BindFrom intent materialization + routing key rejection tests. |
| src/Mocha/test/Mocha.Transport.Postgres.Tests/Routing/PostgresTransportResolverWiringTests.cs | Adds wiring tests for resolver-based dispatch endpoint configuration. |
| src/Mocha/test/Mocha.Transport.Postgres.Tests/Routing/PostgresDestinationResolverTests.cs | Adds resolver unit tests for convention vs explicit destinations. |
| src/Mocha/test/Mocha.Transport.Postgres.Tests/Descriptors/PostgresDescriptorTests.cs | Updates descriptor tests for typed satellites and auto-bind defaults. |
| src/Mocha/test/Mocha.Transport.Postgres.Tests/Topology/PostgresMessageTypeExtensionTests.cs | Updates test stub to satisfy new OnTransport route API. |
| src/Mocha/test/Mocha.Transport.Postgres.Tests/**/snapshots/*.snap | Adds Postgres topology snapshots for new behavior. |
| src/Mocha/test/Mocha.Transport.InMemory.Tests/Topology/InMemoryMessagingTopologyTests.cs | Updates topology duplicate behavior tests (return existing). |
| src/Mocha/test/Mocha.Transport.InMemory.Tests/InMemoryReceiveEndpointBindFromTests.cs | Adds routing key rejection tests for BindFrom on in-memory transport. |
| src/Mocha/test/Mocha.Transport.InMemory.Tests/InMemoryHandlerClaimTests.cs | Adds tests for explicit binding mode and claim convergence behavior. |
| src/Mocha/test/Mocha.Transport.InMemory.Tests/Descriptors/InMemoryUnifiedQueueTests.cs | Adds unified queue delivery and entity-only lowering tests. |
| src/Mocha/test/Mocha.Transport.InMemory.Tests/Descriptors/InMemoryDescriptorTests.cs | Adds auto-bind default/override tests. |
| src/Mocha/test/Mocha.Transport.InMemory.Tests/Behaviors/RequestReplyTests.cs | Adds request/reply regression test under explicit binding mode. |
| src/Mocha/test/Mocha.Transport.InMemory.Tests/Behaviors/PublishOptionsEndpointTests.cs | Adds behavior test for PublishOptions.Endpoint override. |
| src/Mocha/test/Mocha.Transport.InMemory.Tests/Topology/snapshots/*.snap | Adds/updates in-memory topology snapshots for auto-bind suppression behavior. |
| src/Mocha/test/Mocha.Tests/MessageTypes/OutboundRouteTests.cs | Adds tests for HasExplicitDestination semantics. |
| src/Mocha/test/Mocha.Tests/MessageTypes/NeutralSchemeResolutionTests.cs | Adds tests for neutral-scheme default transport claim behavior. |
| src/Mocha/test/Mocha.Tests/MessageTypes/MessageBusBuilderTransportValidationTests.cs | Adds build-time transport invariant validation tests + snapshots. |
| src/Mocha/test/Mocha.Tests/Endpoints/ReceiveTypeBindDescriptorTests.cs | Adds tests for per-type bind intent accumulation and auto-bind resolution rules. |
| src/Mocha/test/Mocha.Tests/Conventions/DefaultNamingConventionsTests.cs | Adds kebab-casing test for error-queue-like pascal input. |
| src/Mocha/test/Mocha.Sagas.Tests/SagaExecutionTests.cs | Removes saga transition auto-provision assertion. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+7
to
+11
| public sealed class ReceiveTypeBindDescriptor : IReceiveTypeBindDescriptor | ||
| { | ||
| private bool? _explicitAutoBind; | ||
| private bool _hasBindFrom; | ||
| private List<BindFromIntent>? _bindFroms; |
Comment on lines
+103
to
+108
| // Merge: explicit AutoBind from the incoming descriptor wins over an implied value; | ||
| // if both are null (neither configured), keep null; BindFroms accumulate. | ||
| var mergedAutoBind = incoming.ResolvedAutoBind ?? existing.AutoBind; | ||
| var mergedBindFroms = existing.BindFroms.Count == 0 && incoming.BindFroms.Count == 0 | ||
| ? (IReadOnlyList<BindFromIntent>)[] | ||
| : [.. existing.BindFroms, .. incoming.BindFroms]; |
Comment on lines
+49
to
+56
| topology.AddQueue( | ||
| new RabbitMQQueueConfiguration | ||
| { | ||
| Name = configuration.QueueName, | ||
| AutoDelete = Kind == ReceiveEndpointKind.Reply, | ||
| AutoProvision = configuration.AutoProvision, | ||
| Provenance = RabbitMQTopologyProvenance.Endpoint | ||
| }); |
Comment on lines
+25
to
+29
| var declaredQueue = transport.Configuration is RabbitMQTransportConfiguration rabbitMQConfiguration | ||
| ? rabbitMQConfiguration.Queues.FirstOrDefault(q => q.Name == queueName) | ||
| : null; | ||
| var inheritedAutoProvision = declaredQueue?.AutoProvision ?? configuration.AutoProvision; | ||
|
|
Comment on lines
+450
to
+453
| // Build the ordered, IsEnabled-filtered interceptor list once, before any transport | ||
| // initialization, so transports may observe it through the feature collection if needed. | ||
| var interceptors = BuildInterceptorList(services); | ||
| features.Set(new BusInterceptorFeature { Interceptors = interceptors }); |
|
|
||
| // assert | ||
| // The inbound route for ImplicitDestinationEvent is created by the handler | ||
| var inboundRoute = runtime.Router.InboundRoutes.Single(r => r.MessageType?.RuntimeType == typeof(ImplicitDestinationEvent)); |
|
|
||
| topology!.AddTopic(config1); | ||
| var first = topology!.AddTopic(config1); | ||
| var countAfterFirst = topology.Topics.Count; |
|
|
||
| topology!.AddQueue(config1); | ||
| var first = topology!.AddQueue(config1); | ||
| var countAfterFirst = topology.Queues.Count; |
c70351e to
c2fd5e7
Compare
- Removed deprecated RabbitMQQueueFrontDoorTests and consolidated queue handling logic. - Updated RabbitMQUnifiedQueueTests to reflect changes in queue naming and binding behavior. - Adjusted RabbitMQReceiveEndpointBindFromTests to utilize the new unified queue approach. - Modified RabbitMQReceiveEndpointTests to streamline queue declarations and handlers. - Enhanced RabbitMQSatelliteTests to ensure proper queue provisioning and consumer attachment. - Updated snapshots to reflect changes in queue source from "endpoint" to "declared" for clarity.
…remove unused logic
…ations across multiple files
- Removed BindFrom method from IReceiveEndpointDescriptor and its implementations in RabbitMQ and Postgres transport descriptors. - Updated ReceiveEndpointConfiguration to eliminate QueueBindFroms property. - Adjusted ReceiveTypeBindDescriptor to remove BindFrom method and related logic. - Simplified tests to reflect changes in binding behavior, ensuring that AutoBind settings are correctly applied without explicit BindFrom declarations. - Cleaned up documentation and comments related to binding behavior across various transport implementations.
| { | ||
| if (transports.IsEmpty) | ||
| { | ||
| throw ThrowHelper.NoTransportForMessageType(route.MessageType); |
Comment on lines
+35
to
+44
| foreach (var transport in transports) | ||
| { | ||
| if (transport.Schema == scheme) | ||
| { | ||
| // Multiple transports with the same schema is not expected in a valid configuration, | ||
| // but we return the first match here since schemas are unique by convention. | ||
| matched = transport; | ||
| break; | ||
| } | ||
| } |
Comment on lines
+72
to
+83
| foreach (var transport in transports) | ||
| { | ||
| if (transport.IsDefaultTransport) | ||
| { | ||
| if (defaultTransport is not null) | ||
| { | ||
| multipleDefaults = true; | ||
| } | ||
|
|
||
| defaultTransport = transport; | ||
| } | ||
| } |
- Changed binding method from BindHandlersExplicitly to BindExplicitly across multiple test files to standardize binding behavior. - Updated snapshot files to reflect changes in RabbitMQ topology descriptions. - Removed obsolete snapshots that are no longer relevant due to the refactor. - Adjusted test assertions to ensure they align with the new binding logic.
…methods and related types
Comment on lines
+253
to
+270
| foreach (var route in router.InboundRoutes) | ||
| { | ||
| if (route.Endpoint is { Transport: { } endpointTransport } endpoint | ||
| && endpointTransport == this | ||
| && route.MessageType is { RuntimeType: { } runtimeType }) | ||
| { | ||
| if (!claimedTypeEndpoints.TryGetValue(runtimeType, out var endpoints)) | ||
| { | ||
| endpoints = []; | ||
| claimedTypeEndpoints[runtimeType] = endpoints; | ||
| } | ||
|
|
||
| if (!endpoints.Contains(endpoint)) | ||
| { | ||
| endpoints.Add(endpoint); | ||
| } | ||
| } | ||
| } |
Comment on lines
+136
to
+143
| foreach (var route in context.Router.GetOutboundByMessageType(messageType)) | ||
| { | ||
| if (route is { HasExplicitDestination: true, Kind: OutboundRouteKind.Publish }) | ||
| { | ||
| var resolution = resolver.ResolveDestination(context.Naming, route); | ||
| return new ChainEntry(resolution.Kind, resolution.Name, IsExplicit: true); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.