I have a basic repository framework that eventually executes a query and maps the results back into a object:
For Example:
public SomeEntity Get(id)
{
return base.GetItem<SomeEntity>
("select * from SomeEntities where id = @idParam",
new { idParam = id});
}
If this looks like Dapper, it is because under the hood GetItem is wrapping Dapper.
I’d like to add automatic caching to GetItem, I have two arguments that come in:
- A string containing the query.
- a anonymous dictionary containing any parameters.
I’m worried that doing a simple prime hash on these parameters would cause cache key collisions, and when you are pulling data from a cache, a collision can be very very bad (I.E. leaking sensitive
information).
So, what techniques do I have that would generate a reasonably sized cache key, while guaranteeing uniqueness based on the input of a query and parameters?
I use the following extension methods to make cached versions of delegates:
And so on for N parameters…
In case it’s not clear from the code, I create a tuple with the arguments, and use the tuple as a key to a dictionary that holds the return values for each set of arguments. Note that every time you call
AsCached, you create a separate cache.You can use these methods as follows: