Skip to content

Instantly share code, notes, and snippets.

@mrpmorris
Created May 3, 2022 14:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrpmorris/402dd53c5303872f10fea3b9b92fdff7 to your computer and use it in GitHub Desktop.
Save mrpmorris/402dd53c5303872f10fea3b9b92fdff7 to your computer and use it in GitHub Desktop.
Fluxor auto-dispatch API calls
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