Mediatr - Where is the right place to invalidate/u

2019-07-11 03:46发布

问题:

This question stems from this other question I had asked about too many interfaces, QCRS and Mediatr library (request/response)

Mediatr: reducing number of DI'ed objects

I have created bunch of commands and queries and I have bunch of behaviors and one of them being is a Cache behaviour that for every query, cache is checked for the value before the query is actually executed against the db. So far this is working great, but the delima comes in when I have an UpdateSomethingCommand, once I update the underlying object in the db, I would like to refresh the cache with what was successfully saved to the db.

My question is specifically when to actually update the cache:

  1. In the UpdateSomethingCommandHandler (this might be breaking the SOLID principal)
  2. Call another command in UpdateSomethingCommandHanlder that is specifically designed to update caches (not sure this is a good design principal)
  3. Introduce another behavior that is specifically designed for updating caches (not sure how to go about this yet)
  4. Is there a better solution?

回答1:

We had a similar need on a project that uses MediatR and ended up incorporating caching into the mediator pipeline, including cache invalidation as you describe.

The basic premise is that we have two different behaviors inserted into the pipeline, one for caching a response from a request, and one for invalidating a cached request response from a different request.

There is a little bit of interplay between the two behaviors in the fact that they need to exchange a cache key in order to invalidate the correct request.

I've recently pulled some of this work into a stand-alone library that in theory can be dropped in as-is to any project using MediatR. In your case, you may just want to look at the techniques we've used here and recreate them as needed.

Rather than repeat everything here and now, I'll point you at the project page where there is some documentation under the Getting Started link on the homepage: https://github.com/Imprise/Imprise.MediatR.Extensions.Caching

In my opinion, the cache invalidation makes the whole process extremely simple and straightforward, but there are cases where we needed finer control over when the invalidation occurs. In these cases the other approach we have taken is to inject an ICache<TRequest, TResponse> cache into INotificationHandlers and then call _cache.Remove(key); manually as needed. Then, from any requests you know should invalidate just raise a notification that is handled by the INotificationHandler e.g. _mediator.Publish(SomethingUpdated);