This article is part of a series called Apizr:
- Apizr – Part 1: A Refit based web api client, but resilient
- Apizr – Part 2: Resilient core features
- Apizr – Part 3: More advanced features
- Apizr – Part 4: Requesting with Mediator pattern (this one)
- Apizr – Part 5: Requesting with Optional pattern
public class MyViewModel { private readonly IApizrManager<IReqResService> _reqResManager; public MyViewModel(IApizrManager<IReqResService> reqResManager) { _reqResManager = reqResManager; } private async Task<List<User>> GetUsersAsync() { try { var userList = await _reqResManager.ExecuteAsync(api => api.GetUsersAsync()); return userList?.Data; } catch (ApizrException<UserList> e) { return e.CachedResult?.Data; } } }
And the same with CRUD apis:
public class MyViewModel { private readonly IApizrManager<ICrudApi<User, int, PagedResult<User>, IDictionary<string, object>>> _userCrudManager; public MyViewModel(IApizrManager<ICrudApi<User, int, PagedResult<User>, IDictionary<string, object>>> userCrudManager) { _userCrudManager = userCrudManager; } private async Task<List<User>> GetUsersAsync() { try { var pagedUsers = await _userCrudManager.ExecuteAsync(api => api.ReadAll()); return pagedUsers?.Data?.ToList(); } catch (ApizrException<PagedResult<User>> e) { return e.CachedResult?.Data?.ToList(); } } }
After MediatR:
Now classic apis with MediatR:
public class MyViewModel { private readonly IMediator _mediator; public MyViewModel(IMediator mediator) { _mediator = mediator; } private async Task<List<User>> GetUsersAsync() { try { var userList = await _mediator.Send(new ExecuteResultRequest<IReqResService, UserList>(api => api.GetUsersAsync())); return userList?.Data; } catch (ApizrException<UserList> e) { return e.CachedResult?.Data; } } }
And the same with CRUD apis:
public class MyViewModel { private readonly IMediator _mediator; public MyViewModel(IMediator mediator) { _mediator = mediator; } private async Task<List<User>> GetUsersAsync() { try { var pagedUsers = await _mediator.Send(new ReadAllQuery<PagedResult<User>>()); return pagedUsers?.Data?.ToList(); } catch (ApizrException<PagedResult<User>> e) { return e.CachedResult?.Data?.ToList(); } } }
I told you, IMediator could rule them all.
You don’t have to resolve/inject each dedicated api interface anymore.
Just send your request with IMediator and it will be intercepted, handled, and you’ll get your result sent right back to you.
In order to use it, please install its dedicated NuGet package called Apizr.Integrations.MediatR.
Then tell it to Apizr by calling:
options => options.WithMediation()
and don’t forget to register MediatR itself as usual:
services.AddMediatR(typeof(Startup));
Everything you need to do is sending your request calling:
var result = await _mediator.Send(YOUR_REQUEST_HERE);
Where YOUR_REQUEST_HERE could be:
Classic apis:
- With no result:
ExecuteUnitRequest<TWebApi>
: execute any method from TWebApiExecuteUnitRequest<TWebApi, TModelData, TApiData>
: execute any method from TWebApi with TModelData mapped* with TApiData
- With result:
ExecuteResultRequest<TWebApi, TApiData>
: execute any method from TWebApi with a TApiData resultExecuteResultRequest<TWebApi, TModelData, TApiData>
: execute any method from TWebApi with a TApiData mapped* to a TModelData resultExecuteResultRequest<TWebApi, TModelResultData, TApiResultData, TApiRequestData, TModelRequestData>
: execute any method from TWebApi, sending TApiRequestData mapped from TModelRequestData, then returning TModelResultData mapped from TApiResultData
* mapped means data mapped with AutoMapper. Please refer to Part 2 blog post.
witch ends to something like:
var userList = await _mediator.Send(new ExecuteResultRequest<IReqResService, UserList>(api => api.GetUsersAsync()));
CRUD apis:
ReadQuery<T>
: get the T entity with intReadQuery<T, TKey>
: get the T entity with TKeyReadAllQuery<TReadAllResult>
: get TReadAllResult with IDictionary<string, object> optional query parametersReadAllQuery<TReadAllParams, TReadAllResult>
: get TReadAllResult with TReadAllParams optional query parametersCreateCommand<T>
: create a T entityUpdateCommand<T>
: update the T entity with intUpdateCommand<TKey, T>
: update the T entity with TKeyDeleteCommand<T>
: delete the T entity with intDeleteCommand<T, TKey>
: delete the T entity with TKey
witch ends to something like:
var pagedUsers = await _mediator.Send(new ReadAllQuery<PagedResult<User>>());
There’s also two typed mediator available for each api interface (classic or CRUD), to help you write things shorter.
For example, with classic apis, resolving/injecting IApizrMediator<TWebApi> gives you access to something shorter like:
var userList = await _reqResMediator.SendFor(api => api.GetUsersAsync());
With CRUD apis, resolving/injecting IApizrCrudMediator<TApiEntity, TApiEntityKey, TReadAllResult, TReadAllParams> gives you access to something shorter like:
var pagedUsers = await _userMediator.SendReadAllQuery();
public class MyViewModel { private readonly IMediator _mediator; private readonly IApizrMediator _apizrMediator; private readonly IApizrMediator<IReqResService> _reqResMediator; private readonly IApizrCrudMediator _apizrCrudMediator; private readonly IApizrCrudMediator<User, int, PagedResult<User>, IDictionary<string, object>> _userMediator; public MyViewModel(IMediator mediator, IApizrMediator apizrMediator, IApizrMediator<IReqResService> reqResMediator, IApizrCrudMediator apizrCrudMediator, IApizrCrudMediator<User, int, PagedResult<User>, IDictionary<string, object>> userMediator) { _mediator = mediator; _apizrMediator = apizrMediator; _reqResMediator = reqResMediator; _apizrCrudMediator = apizrCrudMediator; _userMediator = userMediator; } public ObservableCollection<User>? Users { get; set; } // This is a dummy example presenting all the ways to play with MediatR // You should choose one of it obviously private async Task GetUsersAsync() { IList<User>? users; try { // The classic api interface way var userList = await _mediator.Send(new ExecuteResultRequest<IReqResService, UserList>(api => api.GetUsersAsync())); users = userList.Data; // Or the classic api interface way with Apizr mediator var userList = await _apizrMediator.SendFor<IReqResService>(api => api.GetUsersAsync()); users = userList.Data; // Or the classic api interface way with typed mediator var userList = await _reqResMediator.SendFor(api => api.GetUsersAsync()); users = userList.Data; // Or the crud api interface way var pagedUsers = await _mediator.Send(new ReadAllQuery<PagedResult<User>>()); users = pagedUsers.Data?.ToList(); // Or the crud api interface way with Apizr mediator var pagedUsers = await _apizrCrudMediator.SendReadAllQuery<PagedResult<User>>(); users = pagedUsers.Data?.ToList(); // Or the crud api interface way with typed mediator var pagedUsers = await _userMediator.SendReadAllQuery(); users = pagedUsers.Data?.ToList(); } catch (ApizrException<UserList> e) { return e.CachedResult?.Data; } catch (ApizrException<PagedResult<User>> e) { users = e.CachedResult?.Data; } if(users != null) Users = new ObservableCollection<User>(users); } }