@@ -15,7 +15,7 @@ public sealed class EndpointReference : IManifestExpressionProvider, IValueProvi
1515 // A reference to the endpoint annotation if it exists.
1616 private EndpointAnnotation ? _endpointAnnotation ;
1717 private bool ? _isAllocated ;
18- private readonly NetworkIdentifier _contextNetworkID ;
18+ private readonly NetworkIdentifier ? _contextNetworkID ;
1919
2020 /// <summary>
2121 /// Gets the endpoint annotation associated with the endpoint reference.
@@ -71,7 +71,7 @@ public sealed class EndpointReference : IManifestExpressionProvider, IValueProvi
7171 /// The reference will be resolved in the context of this network, which may be different
7272 /// from the network associated with the default network of the referenced Endpoint.
7373 /// </summary>
74- public NetworkIdentifier ContextNetworkID => _contextNetworkID ;
74+ public NetworkIdentifier ? ContextNetworkID => _contextNetworkID ;
7575
7676 /// <summary>
7777 /// Gets the specified property expression of the endpoint. Defaults to the URL if no property is specified.
@@ -156,7 +156,7 @@ public EndpointReferenceExpression Property(EndpointProperty property)
156156
157157 foreach ( var nes in endpointAnnotation . AllAllocatedEndpoints )
158158 {
159- if ( StringComparers . NetworkID . Equals ( nes . NetworkID , _contextNetworkID ) )
159+ if ( StringComparers . NetworkID . Equals ( nes . NetworkID , _contextNetworkID ?? KnownNetworkIdentifiers . LocalhostNetwork ) )
160160 {
161161 if ( ! nes . Snapshot . IsValueSet )
162162 {
@@ -177,20 +177,20 @@ public EndpointReferenceExpression Property(EndpointProperty property)
177177 /// <param name="endpoint">The endpoint annotation.</param>
178178 /// <param name="contextNetworkID">The ID of the network that serves as the context for the EndpointReference.</param>
179179 /// <remarks>
180- /// Most Aspire resources are accessed in the context of the "localhost" network (host proceses calling other host processes,
181- /// or host processes calling container via mapped ports). This is why EndpointReference assumes this
182- /// context unless specified otherwise. However, for container-to-container, or container-to-host communication,
183- /// you must specify a container network context for the EndpointReference to be resolved correctly .
180+ /// Most Aspire resources are accessed in the context of the "localhost" network (host processes calling other host processes,
181+ /// or host processes calling container via mapped ports). If a <see cref="NetworkIdentifier"/> is specified, the <see cref="EndpointReference"/>
182+ /// will always resolve in the context of that network. If the <see cref="NetworkIdentifier"/> is null, the reference will attempt to resolve itself
183+ /// based on the context of the requesting resource .
184184 /// </remarks>
185- public EndpointReference ( IResourceWithEndpoints owner , EndpointAnnotation endpoint , NetworkIdentifier ? contextNetworkID = null )
185+ public EndpointReference ( IResourceWithEndpoints owner , EndpointAnnotation endpoint , NetworkIdentifier ? contextNetworkID )
186186 {
187187 ArgumentNullException . ThrowIfNull ( owner ) ;
188188 ArgumentNullException . ThrowIfNull ( endpoint ) ;
189189
190190 Resource = owner ;
191191 EndpointName = endpoint . Name ;
192192 _endpointAnnotation = endpoint ;
193- _contextNetworkID = contextNetworkID ?? KnownNetworkIdentifiers . LocalhostNetwork ;
193+ _contextNetworkID = contextNetworkID ;
194194 }
195195
196196 /// <summary>
@@ -221,7 +221,7 @@ public EndpointReference(IResourceWithEndpoints owner, string endpointName, Netw
221221
222222 Resource = owner ;
223223 EndpointName = endpointName ;
224- _contextNetworkID = contextNetworkID ?? KnownNetworkIdentifiers . LocalhostNetwork ;
224+ _contextNetworkID = contextNetworkID ;
225225 }
226226
227227 /// <summary>
@@ -265,7 +265,7 @@ public class EndpointReferenceExpression(EndpointReference endpointReference, En
265265 /// <exception cref="InvalidOperationException">Throws when the selected <see cref="EndpointProperty"/> enumeration is not known.</exception>
266266 public ValueTask < string ? > GetValueAsync ( CancellationToken cancellationToken = default )
267267 {
268- return GetNetworkValueAsync ( null , cancellationToken ) ;
268+ return GetValueAsync ( new ( ) , cancellationToken ) ;
269269 }
270270
271271 /// <summary>
@@ -275,33 +275,25 @@ public class EndpointReferenceExpression(EndpointReference endpointReference, En
275275 /// <param name="cancellationToken">A <see cref="CancellationToken"/>.</param>
276276 /// <returns>A <see cref="string"/> containing the selected <see cref="EndpointProperty"/> value.</returns>
277277 /// <exception cref="InvalidOperationException">Throws when the selected <see cref="EndpointProperty"/> enumeration is not known.</exception>
278- public ValueTask < string ? > GetValueAsync ( ValueProviderContext context , CancellationToken cancellationToken = default )
278+ public async ValueTask < string ? > GetValueAsync ( ValueProviderContext context , CancellationToken cancellationToken = default )
279279 {
280- return context . Network switch
281- {
282- NetworkIdentifier networkID => GetNetworkValueAsync ( networkID , cancellationToken ) ,
283- _ => GetNetworkValueAsync ( null , cancellationToken )
284- } ;
285- }
280+ // If the EndpointReference was for a specific network context, then use that. Otherwise, use the network context from the ValueProviderContext.
281+ // This allows the EndpointReference to be resolved in the context of the caller's network if it was not explicitly set.
282+ var networkContext = Endpoint . ContextNetworkID ?? context . GetNetworkIdentifier ( ) ;
286283
287-
288- private async ValueTask < string ? > GetNetworkValueAsync ( NetworkIdentifier ? context , CancellationToken cancellationToken = default )
289- {
290284 return Property switch
291285 {
292286 EndpointProperty . Scheme => new ( Endpoint . Scheme ) ,
293- EndpointProperty . IPV4Host when context is null || context == KnownNetworkIdentifiers . LocalhostNetwork => "127.0.0.1" ,
287+ EndpointProperty . IPV4Host when networkContext == KnownNetworkIdentifiers . LocalhostNetwork => "127.0.0.1" ,
294288 EndpointProperty . TargetPort when Endpoint . TargetPort is int port => new ( port . ToString ( CultureInfo . InvariantCulture ) ) ,
295289 _ => await ResolveValueWithAllocatedAddress ( ) . ConfigureAwait ( false )
296290 } ;
297291
298292 async ValueTask < string ? > ResolveValueWithAllocatedAddress ( )
299293 {
300- var effectiveContext = context ?? Endpoint . ContextNetworkID ;
301-
302294 // We are going to take the first snapshot that matches the context network ID. In general there might be multiple endpoints for a single service,
303295 // and in future we might need some sort of policy to choose between them, but for now we just take the first one.
304- var nes = Endpoint . EndpointAnnotation . AllAllocatedEndpoints . Where ( nes => nes . NetworkID == effectiveContext ) . FirstOrDefault ( ) ;
296+ var nes = Endpoint . EndpointAnnotation . AllAllocatedEndpoints . Where ( nes => nes . NetworkID == networkContext ) . FirstOrDefault ( ) ;
305297 if ( nes is null )
306298 {
307299 return null ;
0 commit comments