@@ -14,7 +14,7 @@ internal abstract class SendPipelinesOrchestrator
1414 internal abstract Task < ItemsResponse < OfXDataResponse > > ExecuteAsync ( OfXRequest message , IContext context ) ;
1515}
1616
17- internal sealed class SendPipelinesOrchestrator < TAttribute > ( IServiceProvider serviceProvider ) :
17+ internal sealed class SendPipelinesOrchestrator < TAttribute > ( IServiceProvider serviceProvider ) :
1818 SendPipelinesOrchestrator where TAttribute : OfXAttribute
1919{
2020 internal override async Task < ItemsResponse < OfXDataResponse > > ExecuteAsync ( OfXRequest message , IContext context )
@@ -24,18 +24,23 @@ internal override async Task<ItemsResponse<OfXDataResponse>> ExecuteAsync(OfXReq
2424 using var cts = CancellationTokenSource . CreateLinkedTokenSource ( cancellationToken ) ;
2525 cts . CancelAfter ( OfXConstants . DefaultRequestTimeout ) ;
2626 var expressions = JsonSerializer . Deserialize < string [ ] > ( message . Expression ) ;
27- var expressionsResolved = expressions . Select ( originalExpression => new
28- {
29- originalExpression , resolvedExpression = context switch
27+ var parameters = context is IExpressionParameters expressionParameters ? expressionParameters . Parameters : null ;
28+
29+ // Resolve expressions and build lookup in one pass
30+
31+ var ( expressionMap , resolvedExpressions ) = expressions . Aggregate ( (
32+ ExpressionMap : new Dictionary < ExpressionWrapper , string > ( expressions . Length ) ,
33+ ResolvedExpressions : new List < string > ( expressions . Length ) ) ,
34+ ( acc , originalExpression ) =>
3035 {
31- IExpressionParameters expressionParameters => RegexHelpers
32- . ResolvePlaceholders ( originalExpression , expressionParameters . Parameters ) ,
33- _ => RegexHelpers . ResolvePlaceholders ( originalExpression , null )
34- }
35- } ) . ToArray ( ) ;
36+ var resolvedExpression = RegexHelpers . ResolvePlaceholders ( originalExpression , parameters ) ;
37+ if ( acc . ExpressionMap . TryAdd ( new ExpressionWrapper ( resolvedExpression ) , originalExpression ) )
38+ acc . ResolvedExpressions . Add ( resolvedExpression ) ;
39+ return acc ;
40+ } ) ;
3641
37- var expression = JsonSerializer . Serialize ( expressionsResolved
38- . Select ( a => a . resolvedExpression ) . Distinct ( ) ) ;
42+ // Serialize only the distinct resolved expressions
43+ var expression = JsonSerializer . Serialize ( resolvedExpressions ) ;
3944
4045 var request = new RequestOf < TAttribute > ( message . SelectorIds , expression ) ;
4146 var requestContext = new RequestContextImpl < TAttribute > ( request , context ? . Headers ?? [ ] , cts . Token ) ;
@@ -45,16 +50,28 @@ internal override async Task<ItemsResponse<OfXDataResponse>> ExecuteAsync(OfXReq
4550 . Aggregate ( ( ) => handler . RequestAsync ( requestContext ) ,
4651 ( acc , pipeline ) => ( ) => pipeline . HandleAsync ( requestContext , acc ) ) . Invoke ( ) ;
4752
48- result . Items . ForEach ( it => it . OfXValues =
49- [
50- ..expressionsResolved . Select ( ex =>
53+ result . Items . ForEach ( it =>
54+ {
55+ var valueLookup = it . OfXValues
56+ . ToDictionary ( v => new ExpressionWrapper ( v . Expression ) , v => v ) ;
57+
58+ var values = expressionMap . Select ( ex =>
5159 {
52- var valueResult = it . OfXValues . FirstOrDefault ( a => a . Expression == ex . resolvedExpression ) ;
60+ var valueResult = valueLookup . GetValueOrDefault ( ex . Key , null ) ;
5361 return valueResult is null
5462 ? null
55- : new OfXValueResponse { Expression = ex . originalExpression , Value = valueResult . Value } ;
56- } ) . Where ( a => a != null )
57- ] ) ;
63+ : new OfXValueResponse { Expression = ex . Value , Value = valueResult . Value } ;
64+ } ) . Where ( a => a != null ) ;
65+ it . OfXValues = [ ..values ] ;
66+ } ) ;
5867 return result ;
5968 }
69+ }
70+
71+ internal readonly record struct ExpressionWrapper ( string Expression )
72+ {
73+ public bool Equals ( ExpressionWrapper other ) =>
74+ string . Equals ( Expression , other . Expression , StringComparison . Ordinal ) ;
75+
76+ public override int GetHashCode ( ) => Expression ? . GetHashCode ( ) ?? 0 ;
6077}
0 commit comments