Skip to content

Commit 45808a7

Browse files
Refactor internals with concrete types and type aliases
1 parent f92814a commit 45808a7

File tree

3 files changed

+64
-73
lines changed

3 files changed

+64
-73
lines changed

src/AspNet/WebApi/src/Asp.Versioning.WebApi/MediaTypeApiVersionReaderBuilder.cs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ public partial class MediaTypeApiVersionReaderBuilder
2929
var parser = new RouteParser();
3030
var parsedRoute = parser.Parse( template );
3131
var segments = from content in parsedRoute.PathSegments.OfType<IPathContentSegment>()
32-
from segment in content.Subsegments.OfType<IPathParameterSubsegment>()
33-
select segment;
32+
from segment in content.Subsegments.OfType<IPathParameterSubsegment>()
33+
select segment;
3434

3535
if ( segments.Count() > 1 )
3636
{
@@ -108,11 +108,6 @@ private static IReadOnlyList<string> ReadMediaTypePattern(
108108
}
109109
}
110110

111-
if ( version is null )
112-
{
113-
return Array.Empty<string>();
114-
}
115-
116-
return versions is null ? new[] { version } : versions.ToArray();
111+
return ToArray( ref version, versions );
117112
}
118113
}

src/AspNetCore/WebApi/src/Asp.Versioning.Http/MediaTypeApiVersionReaderBuilder.cs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public partial class MediaTypeApiVersionReaderBuilder
4646
return this;
4747
}
4848

49-
private static IReadOnlyList<string> ReadMediaTypePattern(
49+
private static string[] ReadMediaTypePattern(
5050
IReadOnlyList<MediaTypeHeaderValue> mediaTypes,
5151
TemplateMatcher matcher,
5252
string? parameterName )
@@ -103,11 +103,6 @@ private static IReadOnlyList<string> ReadMediaTypePattern(
103103
}
104104
}
105105

106-
if ( version is null )
107-
{
108-
return Array.Empty<string>();
109-
}
110-
111-
return versions is null ? new[] { version } : versions.ToArray();
106+
return ToArray( ref version, versions );
112107
}
113108
}

src/Common/src/Common/MediaTypeApiVersionReaderBuilder.cs

Lines changed: 59 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,36 @@
22

33
#pragma warning disable IDE0079
44
#pragma warning disable SA1121
5-
6-
namespace Asp.Versioning;
5+
#pragma warning disable SA1135
6+
#pragma warning disable SA1200
77

88
#if NETFRAMEWORK
99
using System.Net.Http.Headers;
10+
using HttpRequest = System.Net.Http.HttpRequestMessage;
11+
using MediaTypeHeaderValue = System.Net.Http.Headers.MediaTypeWithQualityHeaderValue;
1012
#else
1113
using Microsoft.AspNetCore.Http;
14+
using Microsoft.Net.Http.Headers;
15+
#endif
16+
17+
namespace Asp.Versioning;
18+
19+
#if !NETFRAMEWORK
1220
using System.Buffers;
1321
#endif
1422
using System.Runtime.CompilerServices;
1523
using System.Text.RegularExpressions;
1624
#if NETFRAMEWORK
17-
using HttpRequest = System.Net.Http.HttpRequestMessage;
1825
using Str = System.String;
1926
using StrComparer = System.StringComparer;
2027
#else
21-
using MediaTypeWithQualityHeaderValue = Microsoft.Net.Http.Headers.MediaTypeHeaderValue;
2228
using Str = Microsoft.Extensions.Primitives.StringSegment;
2329
using StrComparer = Microsoft.Extensions.Primitives.StringSegmentComparer;
2430
#endif
2531
using static Asp.Versioning.ApiVersionParameterLocation;
2632
using static System.StringComparison;
33+
using ReaderCallback = Func<IReadOnlyList<MediaTypeHeaderValue>, IReadOnlyList<string>>;
34+
using SelectorCallback = Func<HttpRequest, IReadOnlyList<string>, IReadOnlyList<string>>;
2735

2836
/// <summary>
2937
/// Represents a builder for an API version reader that reads the value from a media type HTTP header in the request.
@@ -33,8 +41,8 @@ public partial class MediaTypeApiVersionReaderBuilder
3341
private HashSet<string>? parameters;
3442
private HashSet<Str>? included;
3543
private HashSet<Str>? excluded;
36-
private Func<HttpRequest, IReadOnlyList<string>, IReadOnlyList<string>>? select;
37-
private List<Func<IReadOnlyList<MediaTypeWithQualityHeaderValue>, IReadOnlyList<string>>>? readers;
44+
private SelectorCallback? select;
45+
private List<ReaderCallback>? readers;
3846

3947
/// <summary>
4048
/// Adds the name of a media type parameter to be read.
@@ -114,7 +122,7 @@ public virtual MediaTypeApiVersionReaderBuilder Match( [StringSyntax( StringSynt
114122
[CLSCompliant( false )]
115123
#endif
116124
#pragma warning disable CA1716 // Identifiers should not match keywords
117-
public virtual MediaTypeApiVersionReaderBuilder Select( Func<HttpRequest, IReadOnlyList<string>, IReadOnlyList<string>> selector )
125+
public virtual MediaTypeApiVersionReaderBuilder Select( SelectorCallback selector )
118126
#pragma warning restore CA1716 // Identifiers should not match keywords
119127
{
120128
select = selector;
@@ -149,7 +157,7 @@ public virtual IApiVersionReader Build() =>
149157
#if !NETFRAMEWORK
150158
[CLSCompliant( false )]
151159
#endif
152-
protected void AddReader( Func<IReadOnlyList<MediaTypeWithQualityHeaderValue>, IReadOnlyList<string>> reader )
160+
protected void AddReader( ReaderCallback reader )
153161
{
154162
ArgumentNullException.ThrowIfNull( reader );
155163

@@ -158,23 +166,29 @@ protected void AddReader( Func<IReadOnlyList<MediaTypeWithQualityHeaderValue>, I
158166
}
159167

160168
[MethodImpl( MethodImplOptions.AggressiveInlining )]
161-
private static ICollection<Str> EmptyCollection() => Array.Empty<Str>();
169+
private static IReadOnlyList<string> DefaultSelector( HttpRequest request, IReadOnlyList<string> versions ) => versions;
162170

163171
[MethodImpl( MethodImplOptions.AggressiveInlining )]
164-
private static IReadOnlyList<Func<IReadOnlyList<MediaTypeWithQualityHeaderValue>, IReadOnlyList<string>>> EmptyList() =>
165-
Array.Empty<Func<IReadOnlyList<MediaTypeWithQualityHeaderValue>, IReadOnlyList<string>>>();
172+
private static string[] ToArray( ref string? version, List<string>? versions )
173+
{
174+
if ( version is null )
175+
{
176+
return [];
177+
}
166178

167-
private static IReadOnlyList<string> DefaultSelector( HttpRequest request, IReadOnlyList<string> versions ) => versions;
179+
return versions is null ? [version] : [.. versions];
180+
}
168181

169-
private static IReadOnlyList<string> ReadMediaType(
170-
IReadOnlyList<MediaTypeWithQualityHeaderValue> mediaTypes,
182+
private static string[] ReadMediaType(
183+
IReadOnlyList<MediaTypeHeaderValue> mediaTypes,
171184
string pattern )
172185
{
173186
var version = default( string );
174187
var versions = default( List<string> );
175188
var regex = default( Regex );
189+
var count = mediaTypes.Count;
176190

177-
for ( var i = 0; i < mediaTypes.Count; i++ )
191+
for ( var i = 0; i < count; i++ )
178192
{
179193
var mediaType = mediaTypes[i].MediaType;
180194

@@ -203,7 +217,7 @@ private static IReadOnlyList<string> ReadMediaType(
203217
}
204218
else if ( versions == null )
205219
{
206-
versions = new( capacity: mediaTypes.Count - i + 1 )
220+
versions = new( capacity: count - i + 1 )
207221
{
208222
version,
209223
value,
@@ -218,22 +232,18 @@ private static IReadOnlyList<string> ReadMediaType(
218232
}
219233
}
220234

221-
if ( version is null )
222-
{
223-
return Array.Empty<string>();
224-
}
225-
226-
return versions is null ? new[] { version } : versions.ToArray();
235+
return ToArray( ref version, versions );
227236
}
228237

229-
private static IReadOnlyList<string> ReadMediaTypeParameter(
230-
IReadOnlyList<MediaTypeWithQualityHeaderValue> mediaTypes,
238+
private static string[] ReadMediaTypeParameter(
239+
IReadOnlyList<MediaTypeHeaderValue> mediaTypes,
231240
string parameterName )
232241
{
233242
var version = default( string );
234243
var versions = default( List<string> );
244+
var count = mediaTypes.Count;
235245

236-
for ( var i = 0; i < mediaTypes.Count; i++ )
246+
for ( var i = 0; i < count; i++ )
237247
{
238248
var mediaType = mediaTypes[i];
239249

@@ -256,7 +266,7 @@ private static IReadOnlyList<string> ReadMediaTypeParameter(
256266
}
257267
else if ( versions == null )
258268
{
259-
versions = new( capacity: mediaTypes.Count - i + 1 )
269+
versions = new( capacity: count - i + 1 )
260270
{
261271
version,
262272
value,
@@ -269,28 +279,23 @@ private static IReadOnlyList<string> ReadMediaTypeParameter(
269279
}
270280
}
271281

272-
if ( version is null )
273-
{
274-
return Array.Empty<string>();
275-
}
276-
277-
return versions is null ? new[] { version } : versions.ToArray();
282+
return ToArray( ref version, versions );
278283
}
279284

280285
private sealed class BuiltMediaTypeApiVersionReader : IApiVersionReader
281286
{
282-
private readonly IReadOnlyList<string> parameters;
283-
private readonly ICollection<Str> included;
284-
private readonly ICollection<Str> excluded;
285-
private readonly Func<HttpRequest, IReadOnlyList<string>, IReadOnlyList<string>> selector;
286-
private readonly IReadOnlyList<Func<IReadOnlyList<MediaTypeWithQualityHeaderValue>, IReadOnlyList<string>>> readers;
287+
private readonly string[] parameters;
288+
private readonly HashSet<Str> included;
289+
private readonly HashSet<Str> excluded;
290+
private readonly SelectorCallback selector;
291+
private readonly ReaderCallback[] readers;
287292

288293
internal BuiltMediaTypeApiVersionReader(
289-
IReadOnlyList<string> parameters,
290-
ICollection<Str> included,
291-
ICollection<Str> excluded,
292-
Func<HttpRequest, IReadOnlyList<string>, IReadOnlyList<string>> selector,
293-
IReadOnlyList<Func<IReadOnlyList<MediaTypeWithQualityHeaderValue>, IReadOnlyList<string>>> readers )
294+
string[] parameters,
295+
HashSet<Str> included,
296+
HashSet<Str> excluded,
297+
SelectorCallback selector,
298+
ReaderCallback[] readers )
294299
{
295300
this.parameters = parameters;
296301
this.included = included;
@@ -301,18 +306,15 @@ internal BuiltMediaTypeApiVersionReader(
301306

302307
public void AddParameters( IApiVersionParameterDescriptionContext context )
303308
{
304-
if ( context == null )
305-
{
306-
throw new ArgumentNullException( nameof( context ) );
307-
}
309+
ArgumentNullException.ThrowIfNull( context );
308310

309-
if ( parameters.Count == 0 )
311+
if ( parameters.Length == 0 )
310312
{
311313
context.AddParameter( name: string.Empty, MediaTypeParameter );
312314
}
313315
else
314316
{
315-
for ( var i = 0; i < parameters.Count; i++ )
317+
for ( var i = 0; i < parameters.Length; i++ )
316318
{
317319
context.AddParameter( parameters[i], MediaTypeParameter );
318320
}
@@ -321,30 +323,29 @@ public void AddParameters( IApiVersionParameterDescriptionContext context )
321323

322324
public IReadOnlyList<string> Read( HttpRequest request )
323325
{
324-
if ( readers.Count == 0 )
326+
if ( readers.Length == 0 )
325327
{
326328
return Array.Empty<string>();
327329
}
328330

329331
#if NETFRAMEWORK
330332
var headers = request.Headers;
331333
var contentType = request.Content?.Headers.ContentType;
332-
var accept = headers.Accept;
333334
#else
334335
var headers = request.GetTypedHeaders();
335336
var contentType = headers.ContentType;
336-
var accept = headers.Accept;
337337
#endif
338+
var accept = headers.Accept;
338339
var version = default( string );
339340
var versions = default( SortedSet<string> );
340-
var mediaTypes = default( List<MediaTypeWithQualityHeaderValue> );
341+
var mediaTypes = default( List<MediaTypeHeaderValue> );
341342

342343
if ( contentType != null )
343344
{
344345
#if NETFRAMEWORK
345-
mediaTypes = new() { MediaTypeWithQualityHeaderValue.Parse( contentType.ToString() ) };
346+
mediaTypes = [MediaTypeHeaderValue.Parse( contentType.ToString() )];
346347
#else
347-
mediaTypes = new() { contentType };
348+
mediaTypes = [contentType];
348349
#endif
349350
}
350351

@@ -376,13 +377,13 @@ public IReadOnlyList<string> Read( HttpRequest request )
376377

377378
if ( versions == null )
378379
{
379-
return version == null ? Array.Empty<string>() : new[] { version };
380+
return version == null ? Array.Empty<string>() : [version];
380381
}
381382

382383
return selector( request, versions.ToArray() );
383384
}
384385

385-
private void Filter( IList<MediaTypeWithQualityHeaderValue> mediaTypes )
386+
private void Filter( List<MediaTypeHeaderValue> mediaTypes )
386387
{
387388
if ( excluded.Count > 0 )
388389
{
@@ -412,11 +413,11 @@ private void Filter( IList<MediaTypeWithQualityHeaderValue> mediaTypes )
412413
}
413414

414415
private void Read(
415-
List<MediaTypeWithQualityHeaderValue> mediaTypes,
416+
IReadOnlyList<MediaTypeHeaderValue> mediaTypes,
416417
ref string? version,
417418
ref SortedSet<string>? versions )
418419
{
419-
for ( var i = 0; i < readers.Count; i++ )
420+
for ( var i = 0; i < readers.Length; i++ )
420421
{
421422
var result = readers[i]( mediaTypes );
422423

0 commit comments

Comments
 (0)