Premature ITransportAddressResolver access corrupts service
Describe the bug
Description
When using the generic host, it is possible to resolve ITransportAddressResolver before the endpoint has been started. A potential scenario is a hosted service that is trying to use the TransactionalSession (which internally uses the ITransportAddressResolver).
Resolving the ITransportAddressResolver will produce an instance which uses the transportSeam.TransportInfrastructure property which is still null, causing it to throw an NRE once an attempt to translate a transport address is made. Since the service is registered as a singleton, all users of the singleton will receive the invalid instance and thus run into an NRE on any call to the address resolver.
Expected behavior
The endpoint should be able to start successfully.
Additionally, it would be nicer if the code that tries to access the ITransportAddressResolver prematurely will receive an exception, warning about the startup order rather than a corrupted instance which will throw NRE's on usage.
Actual behavior
The endpoint fails to start with an exception:
System.NullReferenceException: Object reference not set to an instance of an object.
at NServiceBus.TransportAddressResolver.ToTransportAddress(QueueAddress queueAddress) in /_/src/NServiceBus.Core/Transports/TransportAddressResolver.cs:line 14
at NServiceBus.TransactionalSession.TransactionalSession.<>c.<Setup>b__1_2(IServiceProvider sp) in /_/src/NServiceBus.TransactionalSession/TransactionalSession.cs:line 74
at NServiceBus.Pipeline.PipelineSettings.<>c__DisplayClass11_0`1.<Register>b__0(IServiceProvider b) in /_/src/NServiceBus.Core/Pipeline/PipelineSettings.cs:line 180
at NServiceBus.Pipeline.RegisterStep.CreateBehavior(IServiceProvider defaultBuilder) in /_/src/NServiceBus.Core/Pipeline/RegisterStep.cs:line 131
at NServiceBus.Pipeline`1.<>c__DisplayClass0_0.<.ctor>b__0(RegisterStep r) in /_/src/NServiceBus.Core/Pipeline/Pipeline.cs:line 27
at System.Linq.Enumerable.SelectListIterator`2.Fill(ReadOnlySpan`1 source, Span`1 destination, Func`2 func)
at System.Linq.Enumerable.SelectListIterator`2.ToArray()
at NServiceBus.Pipeline`1..ctor(IServiceProvider builder, PipelineModifications pipelineModifications) in /_/src/NServiceBus.Core/Pipeline/Pipeline.cs:line 26
at NServiceBus.PipelineComponent.CreatePipeline[T](IServiceProvider builder) in /_/src/NServiceBus.Core/Pipeline/PipelineComponent.cs:line 32
at NServiceBus.ReceiveComponent.Initialize(IServiceProvider builder, RecoverabilityComponent recoverabilityComponent, MessageOperations messageOperations, PipelineComponent pipelineComponent, IPipelineCache pipelineCache, TransportInfrastructure transportInfrastructure, ConsecutiveFailuresConfiguration consecutiveFailuresConfiguration, CancellationToken cancellationToken) in /_/src/NServiceBus.Core/Receiving/ReceiveComponent.cs:line 157
at NServiceBus.StartableEndpoint.Setup(CancellationToken cancellationToken) in /_/src/NServiceBus.Core/StartableEndpoint.cs:line 50
at NServiceBus.ExternallyManagedContainerHost.Start(IServiceProvider externalBuilder, CancellationToken cancellationToken) in /_/src/NServiceBus.Core/Hosting/ExternallyManagedContainerHost.cs:line 41
at NServiceBus.Extensions.Hosting.NServiceBusHostedService.StartAsync(CancellationToken cancellationToken) in /_/src/NServiceBus.Extensions.Hosting/NServiceBusHostedService.cs:line 30
at Microsoft.Extensions.Hosting.Internal.Host.<StartAsync>b__15_1(IHostedService service, CancellationToken token)
at Microsoft.Extensions.Hosting.Internal.Host.ForeachService[T](IEnumerable`1 services, CancellationToken token, Boolean concurrent, Boolean abortOnFirstException, List`1 exceptions, Func`3 operation)
at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)
Versions
Please list the version of the relevant packages or applications in which the bug exists.
Core v8 + TransactionalSession for SQLP
Steps to reproduce
- Create a hosted service which accesses
ITransportAddressResolver - Register the hosted service before calling
UseNServiceBuson the generic host setup - Start the host
Relevant log output
No response
Additional Information
Workarounds
Possible solutions
Additional information
Thanks, we're looking in to it. We need to validate a few things before accepting the proposed fix too.