Created
May 3, 2022 14:41
-
-
Save mrpmorris/402dd53c5303872f10fea3b9b92fdff7 to your computer and use it in GitHub Desktop.
Fluxor auto-dispatch API calls
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
using System.Collections.Concurrent; | |
using System.Reflection; | |
using CarePlace.Client.Services; | |
using Fluxor; | |
using MediatR; | |
namespace XXXXXXX.Client.ViewState; | |
public class ApiEffects | |
{ | |
private static readonly ConcurrentDictionary<Type, Func<object, Task>?> Cache = new(); | |
private readonly IApiService ApiService; | |
private readonly IDispatcher Dispatcher; | |
public ApiEffects(IApiService apiService, IDispatcher dispatcher) | |
{ | |
ApiService = apiService ?? throw new ArgumentNullException(nameof(apiService)); | |
Dispatcher = dispatcher ?? throw new ArgumentNullException(nameof(dispatcher)); | |
} | |
[EffectMethod] | |
public async Task HandleApiCallsAsync(object action, IDispatcher dispatcher) | |
{ | |
Func<object, Task>? apiFunc = Cache.GetOrAdd(action.GetType(),GetApiDispatchFunc); | |
if (apiFunc is null) | |
return; | |
await apiFunc(action); | |
} | |
private async Task ExecuteAsync<TResponse>(IRequest<TResponse> request) | |
{ | |
TResponse response = await ApiService.ExecuteAsync(request); | |
Dispatcher.Dispatch(response); | |
} | |
private Func<object, Task>? GetApiDispatchFunc(Type type) | |
{ | |
Type? stronglyTypedIRequestInterface = type | |
.GetInterfaces() | |
.Where(x => x.IsGenericType) | |
.Where(x => x.GetGenericTypeDefinition() == typeof(IRequest<>)) | |
.FirstOrDefault(); | |
if (stronglyTypedIRequestInterface is null) | |
return null; | |
Type responseType = stronglyTypedIRequestInterface.GetGenericArguments()[0]; | |
MethodInfo genericExecuteAsyncMethod = GetType().GetMethod( | |
nameof(ExecuteAsync), | |
BindingFlags.NonPublic | BindingFlags.Instance)!; | |
MethodInfo stronglyTypedExecuteAsyncMethod = | |
genericExecuteAsyncMethod.MakeGenericMethod(responseType); | |
Func<object, Task> result = | |
(object action) => (Task)stronglyTypedExecuteAsyncMethod.Invoke(this, new[] { action })!; | |
return result; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment