Created
September 10, 2020 18:51
-
-
Save felipebaltazar/199030fee98a7d990f7eed75bad47ae4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
internal sealed class MeuServico : ObjectWithPolicy { | |
#region Fields | |
//Api refit | |
private readonly IApiClient _apiClient; | |
#endregion | |
#region Constructors | |
public MeuServico(string baseUrl) { | |
_apiClient = RestService. | |
.For<IPontoCloudApiClient>(baseUrl); | |
} | |
#endregion | |
#region IUserResource | |
public async Task<UserToken> LoginAsync(UserInfo userInfo) { | |
var loginResult = await RequestWithPolicy(() => _apiClient.LoginAsync(userInfo)).ConfigureAwait(false); | |
return loginResult; | |
} | |
public async Task<UserToken> RefreshLoginAsync(string refreshToken) { | |
var loginResult = await RequestWithPolicy(() => _apiClient.RefreshLoginAsync(refreshToken)).ConfigureAwait(false); | |
return loginResult; | |
} | |
public async Task<UserToken> SignInAsync(UserInfo userInfo) { | |
var signinResult = await RequestWithPolicy(() => _apiClient.SignInAsync(userInfo)).ConfigureAwait(false); | |
return signinResult; | |
} | |
#endregion | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
internal abstract class ObjectWithPolicy { | |
#region Fields | |
private const int MAX_REFRESH_TOKEN_ATTEMPTS = 1; | |
private const int MAX_RETRY_ATTEMPTS = 3; | |
private readonly IAsyncPolicy _authPolicy; | |
private readonly IAsyncPolicy _asyncPolicy; | |
#endregion | |
#region Constructors | |
protected ObjectWithPolicy() : this(null) { } | |
protected ObjectWithPolicy(int? numberOfRetries) { | |
_authPolicy = Policy | |
.HandleInner<ApiException>(AuthStatusCodeFilter) | |
.RetryAsync(MAX_REFRESH_TOKEN_ATTEMPTS, RefreshAuthorizationAsync); | |
_asyncPolicy = Policy | |
.Handle<ApiException>(StatusCodeFilter) | |
.WaitAndRetryAsync(numberOfRetries ?? MAX_RETRY_ATTEMPTS, SleepDuration); | |
} | |
#endregion | |
#region Protected Methods | |
/// <summary> | |
/// Executa a requisição usando uma politica de resiliência | |
/// </summary> | |
/// <typeparam name="T">Resultado da requisição</typeparam> | |
/// <param name="func">Função de requisição</param> | |
/// <returns>Resultado da requisição</returns> | |
protected async Task<T> RequestWithPolicy<T>(Func<Task<T>> func) => | |
await _asyncPolicy.WrapAsync(_authPolicy).ExecuteAsync(func).ConfigureAwait(false); | |
/// <summary> | |
/// Executa a requisição usando uma politica de resiliência | |
/// </summary> | |
/// <param name="func">Função de requisição</param> | |
protected async Task RequestWithPolicy<T>(Func<Task> func) => | |
await _asyncPolicy.WrapAsync(_authPolicy).ExecuteAsync(func).ConfigureAwait(false); | |
/// <summary> | |
/// Executa uma requisição para atualizar token de autorização | |
/// </summary> | |
/// <param name="error"></param> | |
/// <param name="attempt"></param> | |
/// <returns></returns> | |
protected virtual Task RefreshAuthorizationAsync(Exception error, int attempt) => | |
Task.CompletedTask; | |
#endregion | |
#region Private Methods | |
private static bool StatusCodeFilter(ApiException ex) => | |
ex.StatusCode != HttpStatusCode.NotFound && ex.StatusCode != HttpStatusCode.Forbidden; | |
private static bool AuthStatusCodeFilter(ApiException ex) => | |
ex.StatusCode == HttpStatusCode.Unauthorized; | |
private static TimeSpan SleepDuration(int attempt) => | |
TimeSpan.FromSeconds(Math.Pow(2, attempt)); | |
#endregion | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment