skip to Main Content

How can I get dynamic data shared between a custom action attribute and the action method?

My scenario, I am utilizing a custom action attribute to cache data in Redis. In this custom action attribute, I am logging metrics for how long it takes to get data from the cache vs getting it from continuing with the code. For some instances, I cannot utilize this custom action attribute and I’m calling cache methods like, _cache.TryGetAsync(key); inside the action method. TryGetAsync is an extension method I wrote that just wraps the GetAsync(key) call in a try/catch so that if the call to Redis fails, it will continue with getting the data from continuing with the code.

I would still like to try and log metrics when the code is making direct calls to cache via the try extension methods that I wrote.

I was thinking about creating a CacheLogging attribute that I could place on the action method. Then, in the BeforeActionExecutionAsync, I could start the timer and in AfterActionExecutionAsync, stop it and log. But, I need the try extension methods to set the context of where the data is retrieved.

For example, TryGetAsync would set the context to FromCache. Then, TryAddAsync would set it to FromServer. If TryAddAsync is called, that means that the data was not found in the cache and continued to get it from the code and populated the cache with this new data.

The problem is, I can’t figure out how to reliably set this context in the method so that the attribute can read it in the AfterActionExecutionAsync. I thought about DIing a Singleton ICacheContext that the CacheLogging attribute would have access to and could be passed as an optional parameter into the try extension methods. But, with the possibility of the action method being called simultaneously multiple times, the Singleton would need some sort of Dictionary with a unique id per call that both the CacheLogging attribute and the try cache attribute would somehow know that way they knew which call the context was for. But, parameters need to be static/const/etc to be sent to the CacheLogging attribute.

2

Answers


  1. You don’t store performance in attributes.

    If you need to store performance, define global variables that track performance for different methods and commit the data to your datastore every x, or write it to a (text) log.

    Login or Signup to reply.
  2. You should try an AOP approach using Castle Windsor interceptors. See: https://www.tabsoverspaces.com/233716-simple-caching-interceptor-aspect-for-castle-windsor

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search