Reputation: 1259
I have a simple Orders service and would like to implement caching. Here's my request/response and service:
[Route("/order", "GET")]
[Route("/order/{Id}", "GET")]
public class OrderRequest : IReturn<OrderResponse>
{
public int Id { get; set; }
public string Reference1 { get; set; }
public string Reference2 { get; set; }
public DateRange CreatedOn { get; set; }
public DateRange ProcessedOn { get; set; }
public DateRange ShippedOn { get; set; }
public DateRange ModifiedOn { get; set; }
}
public class OrderResponse : IHasResponseStatus
{
public ResponseStatus ResponseStatus { get; set; }
public List<Order> Orders { get; set; }
}
public class OrdersService : Service
{
public object Get(OrderRequest request)
{
var cacheKey = UrnId.Create<OrderResponse>(request.Id.ToString());
return base.RequestContext.ToOptimizedResultUsingCache(base.Cache, cacheKey, new TimeSpan(0,5,0), () =>
{
return GetOrders(request);
});
}
public OrderResponse GetOrders(OrderRequest request)
{
..
}
}
Looking at the documentation a unique key is generated for each cached item. In the examples this is typically the response object + item id. However I would like to cache different types of request. For instance, in my request I can specify a date range. If I make the same request with the same date range then I would like to receive the cached copy. So my question is, what is the best way to generate a unique id based on some or all request parameters? Perhaps use or override GetHashCode on the request DTO? And secondly, if my cache contained many objects of the same type, i.e. OrderResponse, can I delete all items of a given type? Otherwise if I modify an order i'll have no idea which of the cached objects to delete.
Upvotes: 2
Views: 1499
Reputation: 143284
There's nothing special or important about the cacheKey, it just has to be unique for each different item or result-set you want to cache.
If you want it to support different caches for specified date ranges then the variable information needs to be added to the key. You can either use the combination of unique properties on the Request DTO or if it's suitable the base.Request.PathInfo
and/or QueryString to create a unique string to use as the cache key.
And secondly, if my cache contained many objects of the same type, i.e. OrderResponse, can I delete all items of a given type?
No, each CacheProvider is ignorant of what is being cached, the cache invalidation logic is up to the client application to manage.
Otherwise if I modify an order i'll have no idea which of the cached objects to delete.
Right, in which case you either have to put an expiration so it expires itself or make use any advanced features of the underlying cache providers (if they support it). E.g. if you use a MemoryCacheClient
supports the wildcard APIs:
cache.RemoveByPattern("cache:Orders:*");
cache.RemoveByRegex("cache:Orders:.*);
So if you structure your keys hierarchically using the same prefixes you can invalidate all related caches with a single wildcard command.
Upvotes: 1