dotnet / dotnet/aspnetcore

Setting a dynamic duration with ResponseCacheAttribute

Open
#60,516 1 comment 1 reaction 0 assignees View on GitHub
area-middleware
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 6h
Merged PRs (30d)
290

Description

### Is there an existing issue for this?

- [x] I have searched the existing issues

### Is your feature request related to a problem? Please describe the problem.

I am using the `ResponseCacheAttribute`. The duration that I'm trying to set is not a static value and is expected to change per request. I want to take the duration that's been given and apply a transformation on top of it.

`ResponseCacheAttribute` implements a reusable filter that evaluates the values it needs when that filter is first created. What it exposes publicly is also very limited.

This makes reusing the existing logic fairly difficult.

### Describe the solution you'd like

Based on how it works, the most obvious solution would be some kind of factory for the `CacheProfile` that is evaluated per request. At the minimum it should provide access to the requests services. As only one value is changing I would still want to rely on most of the existing behaviour.

By default this could be set up to serve the static `CacheProfile`. Something similar to:

```csharp
public class ResponseCacheAttribute
{
public virtual Func GetCacheProfileFactory(IServiceProvider serviceProvider)
{
var loggerFactory = serviceProvider.GetRequiredService();
var optionsAccessor = serviceProvider.GetRequiredService>();
var cacheProfile = GetCacheProfile(optionsAccessor.Value);

return _ => cacheProfile;
}
}
```

which could be overridden to:

```csharp
public class MyAttribute : ResponseCacheAttribute
{
public override Func GetCacheProfileFactory(IServiceProvider serviceProvider)
{
var loggerFactory = serviceProvider.GetRequiredService();
var optionsAccessor = serviceProvider.GetRequiredService>();

return context =>
{
// get required services... context.HttpContext.

var cacheProfile = GetCacheProfile(optionsAccessor.Value);

cacheProfile.Duration = xyz;

return cacheProfile;
}
}
}
```

### Additional context

I currently do have a workaround to this problem which seems to work, in that I wrap the `ResponseCacheAttribute` in my own filter factory attribute that has the same properties. For each request it creates a new `ResponseCacheAttribute` and assigns each property on it respectively, and then gets it to create the filter. It does feel like a bit of a hack though.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.