@@ -4,19 +4,98 @@ namespace Microsoft.Web.Http.Versioning
44namespace Microsoft . AspNetCore . Mvc . Versioning
55#endif
66{
7+ #if ! WEBAPI
8+ using Http ;
9+ #endif
710 using System ;
811 using System . Linq ;
12+ using System . Collections . Generic ;
13+ using System . Diagnostics . Contracts ;
14+ #if WEBAPI
15+ using HttpRequest = System . Net . Http . HttpRequestMessage ;
16+ #endif
17+ using static System . String ;
918
1019 /// <summary>
11- /// Represents the base implementation of a service API version reader .
20+ /// Provides utility functions for service API version readers .
1221 /// </summary>
13- public abstract partial class ApiVersionReader : IApiVersionReader
22+ public static class ApiVersionReader
1423 {
1524 /// <summary>
16- /// Initializes a new instance of the <see cref="ApiVersionReader"/> class .
25+ /// Returns a new API version reader that is a combination of the specified set .
1726 /// </summary>
18- protected ApiVersionReader ( )
27+ /// <param name="apiVersionReaders">The <see cref="Array">array</see> of
28+ /// <see cref="IApiVersionReader">API version readers</see> to combine.</param>
29+ /// <returns>A new, unioned <see cref="IApiVersionReader">API version reader</see>.</returns>
30+ #if ! WEBAPI
31+ [ CLSCompliant ( false ) ]
32+ #endif
33+ public static IApiVersionReader Combine ( params IApiVersionReader [ ] apiVersionReaders )
34+ {
35+ Arg . NotNull ( apiVersionReaders , nameof ( apiVersionReaders ) ) ;
36+ Contract . Ensures ( Contract . Result < IApiVersionReader > ( ) != null ) ;
37+ Contract . EndContractBlock ( ) ;
38+
39+ if ( apiVersionReaders . Length == 0 )
40+ {
41+ throw new ArgumentException ( SR . ZeroApiVersionReaders , nameof ( apiVersionReaders ) ) ;
42+ }
43+
44+ return new CombinedApiVersionReader ( apiVersionReaders ) ;
45+ }
46+
47+ /// <summary>
48+ /// Returns a new API version reader that is a combination of the specified set.
49+ /// </summary>
50+ /// <param name="apiVersionReaders">The <see cref="IEnumerable{T}">sequence</see> of
51+ /// <see cref="IApiVersionReader">API version readers</see> to combine.</param>
52+ /// <returns>A new, unioned <see cref="IApiVersionReader">API version reader</see>.</returns>
53+ #if ! WEBAPI
54+ [ CLSCompliant ( false ) ]
55+ #endif
56+ public static IApiVersionReader Combine ( IEnumerable < IApiVersionReader > apiVersionReaders )
1957 {
58+ Arg . NotNull ( apiVersionReaders , nameof ( apiVersionReaders ) ) ;
59+ Contract . Ensures ( Contract . Result < IApiVersionReader > ( ) != null ) ;
60+ Contract . EndContractBlock ( ) ;
61+
62+ var items = apiVersionReaders . ToArray ( ) ;
63+
64+ if ( items . Length == 0 )
65+ {
66+ throw new ArgumentException ( SR . ZeroApiVersionReaders , nameof ( apiVersionReaders ) ) ;
67+ }
68+
69+ return new CombinedApiVersionReader ( items ) ;
70+ }
71+
72+ sealed class CombinedApiVersionReader : IApiVersionReader
73+ {
74+ readonly IApiVersionReader [ ] apiVersionReaders ;
75+
76+ internal CombinedApiVersionReader ( IApiVersionReader [ ] apiVersionReaders )
77+ {
78+ Contract . Requires ( apiVersionReaders != null ) ;
79+ Contract . Requires ( apiVersionReaders . Length > 0 ) ;
80+ this . apiVersionReaders = apiVersionReaders ;
81+ }
82+
83+ public string Read ( HttpRequest request )
84+ {
85+ var versions = new HashSet < string > ( StringComparer . OrdinalIgnoreCase ) ;
86+
87+ foreach ( var apiVersionReader in apiVersionReaders )
88+ {
89+ var version = apiVersionReader . Read ( request ) ;
90+
91+ if ( ! IsNullOrEmpty ( version ) )
92+ {
93+ versions . Add ( version ) ;
94+ }
95+ }
96+
97+ return versions . EnsureZeroOrOneApiVersions ( ) ;
98+ }
2099 }
21100 }
22- }
101+ }
0 commit comments