Skip to content

Instantly share code, notes, and snippets.

@Gabboxl
Last active April 11, 2023 13:29
Show Gist options
  • Save Gabboxl/0dd030359c251711bd81be084c7dccc2 to your computer and use it in GitHub Desktop.
Save Gabboxl/0dd030359c251711bd81be084c7dccc2 to your computer and use it in GitHub Desktop.
Wrapper class to apply Polly policies to a Refit http client (+ getting Refit client instance using dependency injection)
using Polly;
using Refit;
using System;
using System.Threading.Tasks;
using Windows.ApplicationModel.Core;
using Windows.System;
using Windows.UI.Xaml.Controls;
namespace ClassevivaPCTO.Utils
{
public class ApiPolicyWrapper<T> where T : class
{
private readonly T _api;
public ApiPolicyWrapper(T api)
{
_api = api;
}
public async Task<TResult> CallApi<TResult>(Func<T, Task<TResult>> apiCall)
{
DispatcherQueue dispatcherQueue = DispatcherQueue.GetForCurrentThread();
var policy = Policy
.Handle<ApiException>()
.RetryAsync(2,
async (ex, count) =>
{
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
Windows.UI.Core.CoreDispatcherPriority.Normal,
async () =>
{
ContentDialog dialog = new ContentDialog();
dialog.Title = "ApiException";
dialog.PrimaryButtonText = "OK";
dialog.DefaultButton = ContentDialogButton.Primary;
dialog.Content =
"Errore: " + ex.Message;
try
{
var result = await dialog.ShowAsync();
}
catch (Exception e)
{
System.Console.WriteLine(e.ToString());
}
}
);
}
);
return await policy.ExecuteAsync(async () => await apiCall(_api));
}
}
}
using ClassevivaPCTO.Services;
using ClassevivaPCTO.Utils;
using Microsoft.AppCenter;
using Microsoft.AppCenter.Analytics;
using Microsoft.AppCenter.Crashes;
using Microsoft.Extensions.DependencyInjection;
using Polly;
using Refit;
using System;
using System.Diagnostics;
using System.Net.Http;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.ApplicationModel.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace ClassevivaPCTO
{
public sealed partial class App : Application
{
private Lazy<ActivationService> _activationService;
private ActivationService ActivationService
{
get { return _activationService.Value; }
}
public IServiceProvider Container { get; }
public IServiceProvider ConfigureDependencyInjection()
{
var serviceCollection = new ServiceCollection();
serviceCollection
.AddRefitClient(typeof(IClassevivaAPI))
.ConfigureHttpClient(
(sp, client) =>
{
client.BaseAddress = new Uri(Endpoint.CurrentEndpoint);
}
);
return serviceCollection.BuildServiceProvider();
}
public App()
{
this.InitializeComponent();
this.Suspending += OnSuspending;
Container = ConfigureDependencyInjection();
_activationService = new Lazy<ActivationService>(CreateActivationService);
}
protected override async void OnLaunched(LaunchActivatedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame == null)
{
rootFrame = new Frame();
rootFrame.NavigationFailed += OnNavigationFailed;
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: caricare lo stato dall'applicazione sospesa in precedenza
}
Window.Current.Content = rootFrame;
}
if (e.PrelaunchActivated == false)
{
if (rootFrame.Content == null)
{
rootFrame.Navigate(typeof(Views.LoginPage), e.Arguments);
}
Window.Current.Activate();
}
if (!e.PrelaunchActivated)
{
await ActivationService.ActivateAsync(e);
}
}
void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
{
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
}
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
//TODO: salvare lo stato dell'applicazione e arrestare eventuali attività eseguite in background
deferral.Complete();
}
protected override async void OnActivated(IActivatedEventArgs args)
{
await ActivationService.ActivateAsync(args);
}
private void OnAppUnhandledException(
object sender,
Windows.UI.Xaml.UnhandledExceptionEventArgs e
)
{
// TODO: Please log and handle the exception as appropriate to your scenario
// For more info see https://docs.microsoft.com/uwp/api/windows.ui.xaml.application.unhandledexception
}
private ActivationService CreateActivationService()
{
return new ActivationService(this, null, null);
}
}
}
using ClassevivaPCTO.Converters;
using ClassevivaPCTO.Services;
using ClassevivaPCTO.Utils;
using ClassevivaPCTO.ViewModels;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Toolkit;
using Microsoft.Toolkit.Uwp;
using Microsoft.Toolkit.Uwp.Helpers;
using Newtonsoft.Json.Linq;
using Polly;
using Polly.Wrap;
using Refit;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using Windows.ApplicationModel.Core;
using Windows.System;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
namespace ClassevivaPCTO.Views
{
/// <summary>
/// Pagina vuota che può essere usata autonomamente oppure per l'esplorazione all'interno di un frame.
/// </summary>
public sealed partial class DashboardPage : Page
{
private readonly IClassevivaAPI apiClient;
private readonly ApiPolicyWrapper<IClassevivaAPI> apiWrapper;
public DashboardPageViewModel DashboardPageViewModel { get; } =
new DashboardPageViewModel();
public DashboardPage()
{
this.InitializeComponent();
App app = (App)App.Current;
apiClient = app.Container.GetService<IClassevivaAPI>();
apiWrapper = new ApiPolicyWrapper<IClassevivaAPI>(apiClient);
}
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
var result1 = await apiWrapper.CallApi(x => x.GetGrades(cardResult.usrId.ToString(), loginResult.Token.ToString()));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment