Aspnetcore: Response caching middleware doesn't allow injection of IResponseCache

Created on 14 Mar 2018  路  13Comments  路  Source: dotnet/aspnetcore

The response caching middleware uses a MemoryCache object to cache responses and it is hardcoded in the public constructor to use it. See: https://github.com/aspnet/ResponseCaching/blob/master/src/Microsoft.AspNetCore.ResponseCaching/ResponseCachingMiddleware.cs. This makes it impossible to provide your own implementation of IResponseCache. I would for example like to create a DistributedResponseCache so I can have better horizontal scaling.

affected-few area-middleware enhancement feature-ResponseCaching severity-minor

Most helpful comment

You can go around this, please take a look here: https://www.tpeczek.com/2018/03/redis-backed-response-caching-in-aspnet.html

All 13 comments

You can go around this, please take a look here: https://www.tpeczek.com/2018/03/redis-backed-response-caching-in-aspnet.html

@tpeczek thanks, this is useful as a temporary hack, but I would prefer an official solution for this.

@angrymrt I went arround, because according to discussion here it has been done on purpose.

@JunTaoLuo What do think next steps here are? Is this work-around fine? Or did you already have a design in mind?

The workaround isn't ideal since it uses reflection but it does get the job done.

@JunTaoLuo how about a dependency on an IResponseCacheFactory that has a Create(IOptions options) method?

Then just pass the IResponseCacheFactory into the internal constructor and use it to create a cache (either distributed or memory).

There are certainly many ways to build this functionality. I'm not sure when we'll triage this work item though.

@JunTaoLuo , unfortunately that workaround no longer works, because this commit removes public access to the IResponseCache interface.
Perhaps could that be made public again?

@JunTaoLuo , unfortunately that workaround no longer works, because this commit removes public access to the IResponseCache interface.
Perhaps could that be made public again?

+1 to that. I ended up copying the AspNetCore ResponseCaching code into our repository and adapted the visibility modifiers. Not proud about that, but now we can upgrade to AspNetCore 3.1.
Why can't the ResponseCaching feature make use of the IDistributedCache interface like so many other AspNetCore features?

I'm poking around with maybe making a nuget package which people can use. It uses aspnetcore as a submodule.
The basic idea is to link to all the asnetcore source files through the submodule into a new project, and then add more IResponseCache implementations to that new project.
The only concern is that I end up going down a rabibit hole of linking to more and more source files... But I think it'll be ok.

_update_
It works! I'm sure it could be improved, but it does the job.
Available on nuget as DistributedResponseCachingMiddleware
@slangeder, does it fulfill the requirements for you're project?

@yringler Thank you very much for creating that package.
A coworker included it in our project today, and it works perfectly.

Possible duplicate or at least closely related to https://github.com/dotnet/aspnetcore/issues/2617.

Can we priorotise this work again? If I was to send in a PR what are the chances of you guys merging it in for the next release?

EDIT:

The current response caching implementatiom is extremely frustrating. It means that an app caches the same data on every node where it's been deployed, which makes it even dumber when you think that you can run more pods in Kubernetes than physical nodes, effectively the same node caching the same data multiple times and wasting valuable and costly cloud resources. Having a configurable public interface to allow an IDistributedCache would make so much more sense.

Not to mention that the more nodes have to cache a response the less likely it is that a cached response will be returned on a request, because there's a chance that each request hits a different node, effectively defeating the purpose of caching in the first place.

Not sure why this was ever approved/shipped in this form, but it needs urgent fixing!

Yes, a resolution of #2617 would also resolve this. (Unless the resolution is also done with private/internal classes.) It's a particular place where the functionality requested in this issue is needed.

Feel free to take a look at my repo mentioned earlier, available on nuget.

It is a replacement for Microsoft.AspNetCore.ResponseCaching which allows customizing the response cache, with a bunch of ready made implementations, for example, one which accepts an injected IDistributedCache. It's implemented with all the official Microsoft code internally via git submodule and csproj linking, so the amount of code in it which isn't coming from Microsoft is pretty tiny.

@slangeder is using it, and I have tested it at my company, although we aren't using it in production yet.

If you see something which needs improvement, it's under the MIT license if you want to fork, or you can drop me a PR.

Was this page helpful?
0 / 5 - 0 ratings