Skip to content

Commit 8622463

Browse files
author
Matthias Gessinger
committed
Extract PolicyManager base class
1 parent 3d03004 commit 8622463

File tree

8 files changed

+203
-172
lines changed

8 files changed

+203
-172
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright (c) .NET Foundation and contributors. All rights reserved.
2+
3+
namespace Asp.Versioning;
4+
5+
/// <summary>
6+
/// Defines the behavior of an API version policy manager.
7+
/// </summary>
8+
/// <typeparam name="TPolicy">The type of the policy.</typeparam>
9+
public interface IPolicyManager<TPolicy>
10+
{
11+
/// <summary>
12+
/// Returns the policy for the specified API and version.
13+
/// </summary>
14+
/// <param name="name">The name of the API.</param>
15+
/// <param name="apiVersion">The API version to get the policy for.</param>
16+
/// <param name="policy">The applicable <typeparamref name="TPolicy">policy</typeparamref>, if any.</param>
17+
/// <returns>True if the <paramref name="policy">policy</paramref> was retrieved; otherwise, false.</returns>
18+
/// <remarks>If <paramref name="name"/> is <c>null</c>, it is assumed the caller intends to match any
19+
/// policy for the specified <paramref name="apiVersion">API version</paramref>. If
20+
/// <paramref name="apiVersion">API version</paramref> is <c>null</c>, it is assumed the caller intends to match
21+
/// any policy for the specified <paramref name="name"/>.</remarks>
22+
bool TryGetPolicy( string? name, ApiVersion? apiVersion, [MaybeNullWhen( false )] out TPolicy policy );
23+
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
// Copyright (c) .NET Foundation and contributors. All rights reserved.
2+
3+
namespace Asp.Versioning;
4+
5+
/// <summary>
6+
/// Provides extension methods for the <see cref="IPolicyManager{T}"/> interface.
7+
/// </summary>
8+
public static class IPolicyManagerExtensions
9+
{
10+
/// <summary>
11+
/// Returns the policy for the specified API and version.
12+
/// </summary>
13+
/// <param name="policyManager">The extended <see cref="IPolicyManager{T}">policy manager</see>.</param>
14+
/// <param name="apiVersion">The API version to get the policy for.</param>
15+
/// <param name="policy">The applicable <typeparamref name="TPolicy">policy</typeparamref>, if any.</param>
16+
/// <typeparam name="TPolicy">The type of policy.</typeparam>
17+
/// <returns>True if the <paramref name="policy">policy</paramref> was retrieved; otherwise, false.</returns>
18+
public static bool TryGetPolicy<TPolicy>(
19+
this IPolicyManager<TPolicy> policyManager,
20+
ApiVersion apiVersion,
21+
[MaybeNullWhen( false )] out TPolicy policy )
22+
{
23+
ArgumentNullException.ThrowIfNull( policyManager );
24+
return policyManager.TryGetPolicy( default, apiVersion, out policy );
25+
}
26+
27+
/// <summary>
28+
/// Returns the policy for the specified API and version.
29+
/// </summary>
30+
/// <param name="policyManager">The extended <see cref="IPolicyManager{T}">policy manager</see>.</param>
31+
/// <param name="name">The name of the API.</param>
32+
/// <param name="policy">The applicable <typeparamref name="TPolicy">policy</typeparamref>, if any.</param>
33+
/// <typeparam name="TPolicy">The type of policy.</typeparam>
34+
/// <returns>True if the <paramref name="policy">policy</paramref> was retrieved; otherwise, false.</returns>
35+
public static bool TryGetPolicy<TPolicy>(
36+
this IPolicyManager<TPolicy> policyManager,
37+
string name,
38+
[MaybeNullWhen( false )] out TPolicy policy )
39+
{
40+
ArgumentNullException.ThrowIfNull( policyManager );
41+
return policyManager.TryGetPolicy( name, default, out policy );
42+
}
43+
44+
/// <summary>
45+
/// Attempts to resolve a policy for the specified name and API version combination.
46+
/// </summary>
47+
/// <param name="policyManager">The extended <see cref="IPolicyManager{T}">policy manager</see>.</param>
48+
/// <param name="name">The name of the API.</param>
49+
/// <param name="apiVersion">The API version to get the policy for.</param>
50+
/// <typeparam name="TPolicy">The type of policy.</typeparam>
51+
/// <returns>The applicable <typeparamref name="TPolicy">policy</typeparamref>, if any.</returns>
52+
/// <remarks>The resolution order is as follows:
53+
/// <list type="bullet">
54+
/// <item><paramref name="name"/> and <paramref name="apiVersion"/></item>
55+
/// <item><paramref name="name"/> only</item>
56+
/// <item><paramref name="apiVersion"/> only</item>
57+
/// </list>
58+
/// </remarks>
59+
public static TPolicy? ResolvePolicyOrDefault<TPolicy>(
60+
this IPolicyManager<TPolicy> policyManager,
61+
string? name,
62+
ApiVersion? apiVersion )
63+
{
64+
ArgumentNullException.ThrowIfNull( policyManager );
65+
66+
if ( policyManager.TryResolvePolicy( name, apiVersion, out var policy ) )
67+
{
68+
return policy;
69+
}
70+
71+
return default;
72+
}
73+
74+
/// <summary>
75+
/// Attempts to resolve a policy for the specified name and API version combination.
76+
/// </summary>
77+
/// <param name="policyManager">The extended <see cref="IPolicyManager{T}">policy manager</see>.</param>
78+
/// <param name="name">The name of the API.</param>
79+
/// <param name="apiVersion">The API version to get the policy for.</param>
80+
/// <param name="policy">The applicable <typeparamref name="TPolicy">policy</typeparamref>, if any.</param>
81+
/// <typeparam name="TPolicy">The type of policy.</typeparam>
82+
/// <returns>True if the <paramref name="policy">policy</paramref> was retrieved; otherwise, false.</returns>
83+
/// <remarks>The resolution order is as follows:
84+
/// <list type="bullet">
85+
/// <item><paramref name="name"/> and <paramref name="apiVersion"/></item>
86+
/// <item><paramref name="name"/> only</item>
87+
/// <item><paramref name="apiVersion"/> only</item>
88+
/// </list>
89+
/// </remarks>
90+
public static bool TryResolvePolicy<TPolicy>(
91+
this IPolicyManager<TPolicy> policyManager,
92+
string? name,
93+
ApiVersion? apiVersion,
94+
[MaybeNullWhen( false )] out TPolicy policy )
95+
{
96+
ArgumentNullException.ThrowIfNull( policyManager );
97+
98+
if ( !string.IsNullOrEmpty( name ) )
99+
{
100+
if ( apiVersion != null && policyManager.TryGetPolicy( name, apiVersion, out policy ) )
101+
{
102+
return true;
103+
}
104+
else if ( policyManager.TryGetPolicy( name!, out policy ) )
105+
{
106+
return true;
107+
}
108+
}
109+
110+
if ( apiVersion != null && policyManager.TryGetPolicy( apiVersion, out policy ) )
111+
{
112+
return true;
113+
}
114+
115+
policy = default!;
116+
return false;
117+
}
118+
}

src/Abstractions/src/Asp.Versioning.Abstractions/ISunsetPolicyManager.cs

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,5 @@ namespace Asp.Versioning;
55
/// <summary>
66
/// Defines the behavior of an API version sunset policy manager.
77
/// </summary>
8-
public interface ISunsetPolicyManager
9-
{
10-
/// <summary>
11-
/// Returns the sunset policy for the specified API and version.
12-
/// </summary>
13-
/// <param name="name">The name of the API.</param>
14-
/// <param name="apiVersion">The API version to get the policy for.</param>
15-
/// <param name="sunsetPolicy">The applicable <see cref="SunsetPolicy">sunset policy</see>, if any.</param>
16-
/// <returns>True if the <paramref name="sunsetPolicy">sunset policy</paramref> was retrieved; otherwise, false.</returns>
17-
/// <remarks>If <paramref name="name"/> is <c>null</c>, it is assumed the caller intends to match any sunset
18-
/// policy for the specified <paramref name="apiVersion">API version</paramref>. If
19-
/// <paramref name="apiVersion">API version</paramref> is <c>null</c>, it is assumed the caller intends to match
20-
/// any sunset policy for the specified <paramref name="name"/>.</remarks>
21-
bool TryGetPolicy( string? name, ApiVersion? apiVersion, [MaybeNullWhen( false )] out SunsetPolicy sunsetPolicy );
22-
}
8+
public interface ISunsetPolicyManager : IPolicyManager<SunsetPolicy>
9+
{ }

src/Abstractions/src/Asp.Versioning.Abstractions/ISunsetPolicyManagerExtensions.cs

Lines changed: 0 additions & 114 deletions
This file was deleted.

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ public partial class SunsetPolicyManager
99
{
1010
private readonly ApiVersioningOptions options;
1111

12+
/// <inheritdoc/>
13+
protected override ApiVersioningOptions Options => options;
14+
1215
/// <summary>
1316
/// Initializes a new instance of the <see cref="SunsetPolicyManager"/> class.
1417
/// </summary>

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ public partial class SunsetPolicyManager
1111
{
1212
private readonly IOptions<ApiVersioningOptions> options;
1313

14+
/// <inheritdoc/>
15+
protected override ApiVersioningOptions Options => options.Value;
16+
1417
/// <summary>
1518
/// Initializes a new instance of the <see cref="SunsetPolicyManager"/> class.
1619
/// </summary>
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright (c) .NET Foundation and contributors. All rights reserved.
2+
3+
namespace Asp.Versioning;
4+
5+
/// <inheritdoc/>
6+
public abstract class PolicyManager<TPolicy, TPolicyBuilder> : IPolicyManager<TPolicy>
7+
where TPolicyBuilder : IPolicyBuilder<TPolicy>
8+
{
9+
private Dictionary<PolicyKey, TPolicy>? policies;
10+
11+
/// <summary>
12+
/// Gets the current api versioning options.
13+
/// </summary>
14+
/// <value>The api versioning options.</value>
15+
protected abstract ApiVersioningOptions Options { get; }
16+
17+
/// <inheritdoc />
18+
public virtual bool TryGetPolicy(
19+
string? name,
20+
ApiVersion? apiVersion,
21+
[MaybeNullWhen( false )] out TPolicy policy )
22+
{
23+
if ( string.IsNullOrEmpty( name ) && apiVersion == null )
24+
{
25+
policy = default!;
26+
return false;
27+
}
28+
29+
policies ??= BuildPolicies( Options );
30+
31+
var key = new PolicyKey( name, apiVersion );
32+
33+
return policies.TryGetValue( key, out policy );
34+
}
35+
36+
private static Dictionary<PolicyKey, TPolicy> BuildPolicies( ApiVersioningOptions options )
37+
{
38+
var builders = options.Policies.OfType<TPolicyBuilder>();
39+
var mapping = new Dictionary<PolicyKey, TPolicy>( capacity: builders.Count );
40+
41+
for ( var i = 0; i < builders.Count; i++ )
42+
{
43+
var builder = builders[i];
44+
var policy = builder.Build();
45+
var key = new PolicyKey( builder.Name, builder.ApiVersion );
46+
47+
mapping[key] = policy;
48+
}
49+
50+
return mapping;
51+
}
52+
}

0 commit comments

Comments
 (0)