Open reactmanju opened 3 weeks ago
I am developing a Caching Behavior using mediatR as below to intercept (Pre-Processor) the call to a request Handler
public class CachingBehaviour <TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> where TRequest : MediatR.IRequest
My Request object is below
public class GetAllEmploymentTypesQuery : IRequest<IDomainResult<IEnumerable< EmploymentType >>>, ICachable
Definition of Request Handler is as below
public class GetAllEmploymentTypesQueryHandler : IRequestHandler<GetAllEmploymentTypesQuery, IDomainResult<IEnumerable< EmploymentType >>>
In the request handler I return return DomainResult.Success<IEnumerable< EmploymentType >> (result.ToList());
Within the CachingBehaviour I would like to serialize and deserialize the DomainResult<IEnumerable< EmploymentType >>, I am having issues while Deserializing. Any suggestions on how to achieve this will help a lot.
Hey,
As I understand, you're using the MediatR.Extensions.Caching extension and the distributed cache (as the MemoryCache
doesn't require serialisation). As the IDistributedCache
relies on binary serialisation (with classes marked by the [Serializable]
attribute), the topic here is "Implementing binary serialisation for the MediatR caching integration". Correct me here if I'm wrong.
The main obstacle here is that the IDomainResult<T>
type is essentially a wrapper on the object, the IEnumerable<EmploymentType>
in your case, which caries
IEnumerable<EmploymentType>
object.IDomainResult
).Hence, to serialise the IDomainResult<T>
, all the nested T
's must also be serializable. I'm hesitant to enforce this constraint, as it'd over-complicate the primary use case, but it can be left unenforced (if the T
can't be serialised, then the operation would just fail).
So, the solution you're after would be a special IDistributedCache implementation for all the domain result types (IDomainResult
, IDomainResult<T>
along with tuples (T, IDomainResult)
) and an extension method to register it.
Perhaps IMemoryCache and HybridCache should also be added to the pot.
Does it sound about right?
Perhaps the fastest (and independent) option for IDomainResult<T>
caching in MediatR would be implementing a bespoke CachingBehavior
class that caches/serialises the T
, IDomainResult.Status
and IDomainResult.Errors
. On resolving the value from the cache, it could form the IDomainResult<T>
instance by calling something like
IDomainResult<T> ResolveFromCache<T>()
{
// 1. Get the `value` (type of T), `status` (type of IDomainResult.Status) and the `errors` (type of IDomainResult.Errors)
....
// 2. Form the required type by leveraging the implicit operator https://github.com/AKlaus/DomainResult/blob/7d82bc63d46871522882e3b457d0a0caf109b382/src/Common/DomainResultOfT.cs#L75
return (value, new DomainResult(status, errors))
}
A more straightforward option could be caching just the T
for successful requests only, as the failure can have intermittent and circumstantial causes.
Let me know if these are viable directions.
How can we Deserialize DomainResults.Common.DomainResult as it does not contain default constructor. Can serialization will be supported?