Skip to content

Commit c13662b

Browse files
authored
Refactor TokenCredential.Create (Azure#23927)
* Refactor TokenCredential.Create
1 parent 0482e78 commit c13662b

File tree

8 files changed

+97
-98
lines changed

8 files changed

+97
-98
lines changed

sdk/core/Azure.Core/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
### Features Added
66

7-
- Added `TokenCredential.Create` static method, which returns an instance of `TokenCredential` that uses the supplied delgates to produce an `AccessToken`. This would most typically be used when an token has previously been obtained from some other source and that token needs to be returned by a `TokenCredential` instance.
7+
- Added the static `DelegatedTokenCredential` type with a `Create` method, which returns an instance of `TokenCredential` that uses the supplied delgates to produce an `AccessToken`. This would most typically be used when an token has previously been obtained from some other source and that token needs to be returned by a `TokenCredential` instance.
88

99
### Breaking Changes
1010

sdk/core/Azure.Core/api/Azure.Core.net461.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,11 @@ public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.
262262
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
263263
public override string? ToString() { throw null; }
264264
}
265+
public static partial class DelegatedTokenCredential
266+
{
267+
public static Azure.Core.TokenCredential Create(System.Func<Azure.Core.TokenRequestContext, System.Threading.CancellationToken, Azure.Core.AccessToken> getToken) { throw null; }
268+
public static Azure.Core.TokenCredential Create(System.Func<Azure.Core.TokenRequestContext, System.Threading.CancellationToken, Azure.Core.AccessToken> getToken, System.Func<Azure.Core.TokenRequestContext, System.Threading.CancellationToken, System.Threading.Tasks.ValueTask<Azure.Core.AccessToken>> getTokenAsync) { throw null; }
269+
}
265270
public partial class DiagnosticsOptions
266271
{
267272
internal DiagnosticsOptions() { }
@@ -471,9 +476,6 @@ internal RetryOptions() { }
471476
public abstract partial class TokenCredential
472477
{
473478
protected TokenCredential() { }
474-
public static Azure.Core.TokenCredential Create(System.Func<Azure.Core.TokenRequestContext, System.Threading.CancellationToken, Azure.Core.AccessToken> getToken) { throw null; }
475-
public static Azure.Core.TokenCredential Create(System.Func<Azure.Core.TokenRequestContext, System.Threading.CancellationToken, Azure.Core.AccessToken> getToken, System.Func<Azure.Core.TokenRequestContext, System.Threading.CancellationToken, System.Threading.Tasks.ValueTask<Azure.Core.AccessToken>> getTokenAsync) { throw null; }
476-
public static Azure.Core.TokenCredential Create(System.Func<Azure.Core.TokenRequestContext, System.Threading.CancellationToken, System.Threading.Tasks.ValueTask<Azure.Core.AccessToken>> getTokenAsync) { throw null; }
477479
public abstract Azure.Core.AccessToken GetToken(Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken);
478480
public abstract System.Threading.Tasks.ValueTask<Azure.Core.AccessToken> GetTokenAsync(Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken);
479481
}

sdk/core/Azure.Core/api/Azure.Core.net5.0.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,11 @@ public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.
262262
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
263263
public override string? ToString() { throw null; }
264264
}
265+
public static partial class DelegatedTokenCredential
266+
{
267+
public static Azure.Core.TokenCredential Create(System.Func<Azure.Core.TokenRequestContext, System.Threading.CancellationToken, Azure.Core.AccessToken> getToken) { throw null; }
268+
public static Azure.Core.TokenCredential Create(System.Func<Azure.Core.TokenRequestContext, System.Threading.CancellationToken, Azure.Core.AccessToken> getToken, System.Func<Azure.Core.TokenRequestContext, System.Threading.CancellationToken, System.Threading.Tasks.ValueTask<Azure.Core.AccessToken>> getTokenAsync) { throw null; }
269+
}
265270
public partial class DiagnosticsOptions
266271
{
267272
internal DiagnosticsOptions() { }
@@ -471,9 +476,6 @@ internal RetryOptions() { }
471476
public abstract partial class TokenCredential
472477
{
473478
protected TokenCredential() { }
474-
public static Azure.Core.TokenCredential Create(System.Func<Azure.Core.TokenRequestContext, System.Threading.CancellationToken, Azure.Core.AccessToken> getToken) { throw null; }
475-
public static Azure.Core.TokenCredential Create(System.Func<Azure.Core.TokenRequestContext, System.Threading.CancellationToken, Azure.Core.AccessToken> getToken, System.Func<Azure.Core.TokenRequestContext, System.Threading.CancellationToken, System.Threading.Tasks.ValueTask<Azure.Core.AccessToken>> getTokenAsync) { throw null; }
476-
public static Azure.Core.TokenCredential Create(System.Func<Azure.Core.TokenRequestContext, System.Threading.CancellationToken, System.Threading.Tasks.ValueTask<Azure.Core.AccessToken>> getTokenAsync) { throw null; }
477479
public abstract Azure.Core.AccessToken GetToken(Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken);
478480
public abstract System.Threading.Tasks.ValueTask<Azure.Core.AccessToken> GetTokenAsync(Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken);
479481
}

sdk/core/Azure.Core/api/Azure.Core.netcoreapp2.1.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,11 @@ public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.
262262
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
263263
public override string? ToString() { throw null; }
264264
}
265+
public static partial class DelegatedTokenCredential
266+
{
267+
public static Azure.Core.TokenCredential Create(System.Func<Azure.Core.TokenRequestContext, System.Threading.CancellationToken, Azure.Core.AccessToken> getToken) { throw null; }
268+
public static Azure.Core.TokenCredential Create(System.Func<Azure.Core.TokenRequestContext, System.Threading.CancellationToken, Azure.Core.AccessToken> getToken, System.Func<Azure.Core.TokenRequestContext, System.Threading.CancellationToken, System.Threading.Tasks.ValueTask<Azure.Core.AccessToken>> getTokenAsync) { throw null; }
269+
}
265270
public partial class DiagnosticsOptions
266271
{
267272
internal DiagnosticsOptions() { }
@@ -471,9 +476,6 @@ internal RetryOptions() { }
471476
public abstract partial class TokenCredential
472477
{
473478
protected TokenCredential() { }
474-
public static Azure.Core.TokenCredential Create(System.Func<Azure.Core.TokenRequestContext, System.Threading.CancellationToken, Azure.Core.AccessToken> getToken) { throw null; }
475-
public static Azure.Core.TokenCredential Create(System.Func<Azure.Core.TokenRequestContext, System.Threading.CancellationToken, Azure.Core.AccessToken> getToken, System.Func<Azure.Core.TokenRequestContext, System.Threading.CancellationToken, System.Threading.Tasks.ValueTask<Azure.Core.AccessToken>> getTokenAsync) { throw null; }
476-
public static Azure.Core.TokenCredential Create(System.Func<Azure.Core.TokenRequestContext, System.Threading.CancellationToken, System.Threading.Tasks.ValueTask<Azure.Core.AccessToken>> getTokenAsync) { throw null; }
477479
public abstract Azure.Core.AccessToken GetToken(Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken);
478480
public abstract System.Threading.Tasks.ValueTask<Azure.Core.AccessToken> GetTokenAsync(Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken);
479481
}

sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,11 @@ public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.
262262
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
263263
public override string? ToString() { throw null; }
264264
}
265+
public static partial class DelegatedTokenCredential
266+
{
267+
public static Azure.Core.TokenCredential Create(System.Func<Azure.Core.TokenRequestContext, System.Threading.CancellationToken, Azure.Core.AccessToken> getToken) { throw null; }
268+
public static Azure.Core.TokenCredential Create(System.Func<Azure.Core.TokenRequestContext, System.Threading.CancellationToken, Azure.Core.AccessToken> getToken, System.Func<Azure.Core.TokenRequestContext, System.Threading.CancellationToken, System.Threading.Tasks.ValueTask<Azure.Core.AccessToken>> getTokenAsync) { throw null; }
269+
}
265270
public partial class DiagnosticsOptions
266271
{
267272
internal DiagnosticsOptions() { }
@@ -471,9 +476,6 @@ internal RetryOptions() { }
471476
public abstract partial class TokenCredential
472477
{
473478
protected TokenCredential() { }
474-
public static Azure.Core.TokenCredential Create(System.Func<Azure.Core.TokenRequestContext, System.Threading.CancellationToken, Azure.Core.AccessToken> getToken) { throw null; }
475-
public static Azure.Core.TokenCredential Create(System.Func<Azure.Core.TokenRequestContext, System.Threading.CancellationToken, Azure.Core.AccessToken> getToken, System.Func<Azure.Core.TokenRequestContext, System.Threading.CancellationToken, System.Threading.Tasks.ValueTask<Azure.Core.AccessToken>> getTokenAsync) { throw null; }
476-
public static Azure.Core.TokenCredential Create(System.Func<Azure.Core.TokenRequestContext, System.Threading.CancellationToken, System.Threading.Tasks.ValueTask<Azure.Core.AccessToken>> getTokenAsync) { throw null; }
477479
public abstract Azure.Core.AccessToken GetToken(Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken);
478480
public abstract System.Threading.Tasks.ValueTask<Azure.Core.AccessToken> GetTokenAsync(Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken);
479481
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using System;
5+
using System.Threading;
6+
using System.Threading.Tasks;
7+
using Azure.Core.Pipeline;
8+
9+
namespace Azure.Core
10+
{
11+
/// <summary>
12+
/// A factory for creating a delegated <see cref="TokenCredential"/> capable of providing an OAuth token.
13+
/// </summary>
14+
public static class DelegatedTokenCredential
15+
{
16+
/// <summary>
17+
/// Creates a static <see cref="TokenCredential"/> that accepts delegates which will produce an <see cref="AccessToken"/>.
18+
/// </summary>
19+
/// <remarks>
20+
/// Typically, the <see cref="TokenCredential"/> created by this method is for use when you have already obtained an <see cref="AccessToken"/>
21+
/// from some other source and need a <see cref="TokenCredential"/> that will simply return that token. Because the static token can expire,
22+
/// the delegates offer a mechanism to handle <see cref="AccessToken"/> renewal.
23+
/// </remarks>
24+
/// <param name="getToken">A delegate that returns an <see cref="AccessToken"/>.</param>
25+
/// <param name="getTokenAsync">A delegate that returns a <see cref="ValueTask"/> of type <see cref="AccessToken"/>.</param>
26+
/// <returns></returns>
27+
public static TokenCredential Create(
28+
Func<TokenRequestContext, CancellationToken, AccessToken> getToken,
29+
Func<TokenRequestContext, CancellationToken, ValueTask<AccessToken>> getTokenAsync) => new StaticTokenCredential(getToken, getTokenAsync);
30+
31+
/// <summary>
32+
/// Creates a static <see cref="TokenCredential"/> that accepts delegates which will produce an <see cref="AccessToken"/>.
33+
/// </summary>
34+
/// <remarks>
35+
/// Typically, the <see cref="TokenCredential"/> created by this method is for use when you have already obtained an <see cref="AccessToken"/>
36+
/// from some other source and need a <see cref="TokenCredential"/> that will simply return that token. Because the static token can expire,
37+
/// the delegates offer a mechanism to handle <see cref="AccessToken"/> renewal.
38+
/// </remarks>
39+
/// <param name="getToken">A delegate that returns an <see cref="AccessToken"/>.</param>
40+
/// <returns></returns>
41+
public static TokenCredential Create(
42+
Func<TokenRequestContext, CancellationToken, AccessToken> getToken) => new StaticTokenCredential(getToken);
43+
44+
private class StaticTokenCredential : TokenCredential
45+
{
46+
private readonly Func<TokenRequestContext, CancellationToken, AccessToken> _getToken;
47+
private readonly Func<TokenRequestContext, CancellationToken, ValueTask<AccessToken>> _getTokenAsync;
48+
49+
internal StaticTokenCredential(
50+
Func<TokenRequestContext, CancellationToken, AccessToken> getToken,
51+
Func<TokenRequestContext, CancellationToken, ValueTask<AccessToken>> getTokenAsync)
52+
{
53+
_getToken = getToken;
54+
_getTokenAsync = getTokenAsync;
55+
}
56+
57+
internal StaticTokenCredential(
58+
Func<TokenRequestContext, CancellationToken, AccessToken> getToken)
59+
{
60+
_getToken = getToken;
61+
_getTokenAsync = (context, token) => new ValueTask<AccessToken>(_getToken(context, token));
62+
}
63+
64+
/// <inheritdoc cref="GetTokenAsync"/>
65+
public override ValueTask<AccessToken> GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken) =>
66+
_getTokenAsync(requestContext, cancellationToken);
67+
68+
/// <inheritdoc cref="GetToken"/>
69+
public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken) =>
70+
_getToken(requestContext, cancellationToken);
71+
}
72+
}
73+
}

sdk/core/Azure.Core/src/TokenCredential.cs

Lines changed: 0 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -30,86 +30,5 @@ public abstract class TokenCredential
3030
/// <returns>A valid <see cref="AccessToken"/>.</returns>
3131
/// <remarks>Caching and management of the lifespan for the <see cref="AccessToken"/> is considered the responsibility of the caller: each call should request a fresh token being requested.</remarks>
3232
public abstract AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken);
33-
34-
/// <summary>
35-
/// Creates a static <see cref="TokenCredential"/> that accepts delegates which will produce an <see cref="AccessToken"/>.
36-
/// </summary>
37-
/// <remarks>
38-
/// Typically, the <see cref="TokenCredential"/> created by this method is for use when you have already obtained an <see cref="AccessToken"/>
39-
/// from some other source and need a <see cref="TokenCredential"/> that will simply return that token. Because the static token can expire,
40-
/// the delegates offer a mechanism to handle <see cref="AccessToken"/> renewal.
41-
/// </remarks>
42-
/// <param name="getToken">A delegate that returns an <see cref="AccessToken"/>.</param>
43-
/// <param name="getTokenAsync">A delegate that returns a <see cref="ValueTask"/> of type <see cref="AccessToken"/>.</param>
44-
/// <returns></returns>
45-
public static TokenCredential Create(
46-
Func<TokenRequestContext, CancellationToken, AccessToken> getToken,
47-
Func<TokenRequestContext, CancellationToken, ValueTask<AccessToken>> getTokenAsync) => new StaticTokenCredential(getToken, getTokenAsync);
48-
49-
/// <summary>
50-
/// Creates a static <see cref="TokenCredential"/> that accepts delegates which will produce an <see cref="AccessToken"/>.
51-
/// </summary>
52-
/// <remarks>
53-
/// Typically, the <see cref="TokenCredential"/> created by this method is for use when you have already obtained an <see cref="AccessToken"/>
54-
/// from some other source and need a <see cref="TokenCredential"/> that will simply return that token. Because the static token can expire,
55-
/// the delegates offer a mechanism to handle <see cref="AccessToken"/> renewal.
56-
/// </remarks>
57-
/// <param name="getToken">A delegate that returns an <see cref="AccessToken"/>.</param>
58-
/// <returns></returns>
59-
public static TokenCredential Create(
60-
Func<TokenRequestContext, CancellationToken, AccessToken> getToken) => new StaticTokenCredential(getToken);
61-
62-
/// <summary>
63-
/// Creates a static <see cref="TokenCredential"/> that accepts delegates which will produce an <see cref="AccessToken"/>.
64-
/// </summary>
65-
/// <remarks>
66-
/// Typically, the <see cref="TokenCredential"/> created by this method is for use when you have already obtained an <see cref="AccessToken"/>
67-
/// from some other source and need a <see cref="TokenCredential"/> that will simply return that token. Because the static token can expire,
68-
/// the delegates offer a mechanism to handle <see cref="AccessToken"/> renewal.
69-
/// </remarks>
70-
/// <param name="getTokenAsync">A delegate that returns a <see cref="ValueTask"/> of type <see cref="AccessToken"/>.
71-
/// If <see cref="GetToken"/> is called, the provided delegate will be executed sync over async.</param>
72-
/// <returns></returns>
73-
public static TokenCredential Create(
74-
Func<TokenRequestContext, CancellationToken, ValueTask<AccessToken>> getTokenAsync) => new StaticTokenCredential(getTokenAsync);
75-
76-
private class StaticTokenCredential : TokenCredential
77-
{
78-
private readonly Func<TokenRequestContext, CancellationToken, AccessToken> _getToken;
79-
private readonly Func<TokenRequestContext, CancellationToken, ValueTask<AccessToken>> _getTokenAsync;
80-
81-
internal StaticTokenCredential(
82-
Func<TokenRequestContext, CancellationToken, AccessToken> getToken,
83-
Func<TokenRequestContext, CancellationToken, ValueTask<AccessToken>> getTokenAsync)
84-
{
85-
_getToken = getToken;
86-
_getTokenAsync = getTokenAsync;
87-
}
88-
89-
internal StaticTokenCredential(
90-
Func<TokenRequestContext, CancellationToken, AccessToken> getToken)
91-
{
92-
_getToken = getToken;
93-
_getTokenAsync = (context, token) => new ValueTask<AccessToken>(_getToken(context, token));
94-
}
95-
96-
internal StaticTokenCredential(
97-
Func<TokenRequestContext, CancellationToken, ValueTask<AccessToken>> getTokenAsync)
98-
{
99-
_getToken = (context, token) => getTokenAsync(context, token)
100-
#pragma warning disable AZC0102 // Do not use GetAwaiter().GetResult(). Use the TaskExtensions.EnsureCompleted() extension method instead.
101-
.GetAwaiter().GetResult();
102-
#pragma warning restore AZC0102 // Do not use GetAwaiter().GetResult(). Use the TaskExtensions.EnsureCompleted() extension method instead.
103-
_getTokenAsync = getTokenAsync;
104-
}
105-
106-
/// <inheritdoc cref="GetTokenAsync"/>
107-
public override ValueTask<AccessToken> GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken) =>
108-
_getTokenAsync(requestContext, cancellationToken);
109-
110-
/// <inheritdoc cref="GetToken"/>
111-
public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken) =>
112-
_getToken(requestContext, cancellationToken);
113-
}
11433
}
11534
}

sdk/core/Azure.Core/tests/StaticTokenCredentialTests.cs renamed to sdk/core/Azure.Core/tests/DelegatedTokenCredentialTests.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
namespace Azure.Core.Tests
1111
{
12-
public class StaticTokenCredentialTests
12+
public class DelegatedTokenCredentialTests
1313
{
1414
private static string[] scopes = { "https://default.mock.auth.scope/.default" };
1515
private static CancellationToken ctx = new CancellationTokenSource(TimeSpan.FromMinutes(5)).Token;
@@ -35,9 +35,8 @@ private static IEnumerable<object[]> Credentials()
3535
await Task.Yield();
3636
return staticToken;
3737
};
38-
yield return new object[] { TokenCredential.Create(getTokenAsync) };
39-
yield return new object[] { TokenCredential.Create(getToken) };
40-
yield return new object[] { TokenCredential.Create(getToken, getTokenAsync) };
38+
yield return new object[] { DelegatedTokenCredential.Create(getToken) };
39+
yield return new object[] { DelegatedTokenCredential.Create(getToken, getTokenAsync) };
4140
}
4241

4342
[TestCaseSource(nameof(Credentials))]

0 commit comments

Comments
 (0)