This project demonstrates how to implement efficient in-memory caching using IMemoryCache in .NET applications. Originally built for .NET Core and progressively upgraded to .NET 10, this implementation showcases modern caching patterns specifically designed for monolithic environments.
For distributed caching approaches, check out my other project using Redis.
I have also blogged with a full explanation of the core concepts.
This project has evolved through several .NET versions:
- Started with .NET Core 3.1
- Updated to .NET 6 with minimal hosting model
- Upgraded to .NET 9.0 with modern C# features
- Currently multi-targets every in-support .NET version (8 LTS, 9 STS, 10 LTS), validated by a CI matrix
main multi-targets the .NET versions that are currently in support and is
validated against each of them in CI. As versions reach end-of-life they are
dropped from the target frameworks. For an older, out-of-support release, check
out the matching tag (e.g. git checkout v9.0). Browse all snapshots on the
tags page.
| Tag | .NET version | Support status |
|---|---|---|
v10.0 |
.NET 10 | LTS |
v9.0 |
.NET 9.0 | STS (EOL Nov 2026) |
v6.0 |
.NET 6 | EOL |
v3.1 |
.NET Core 3.1 | EOL |
Note: tags are immutable snapshots, not maintained branches. Older, out-of-support versions are preserved for reference only.
To stay current with low upkeep, main targets every in-support .NET
version and the CI matrix builds and tests against each one. When a version
reaches end-of-life it is removed from <TargetFrameworks> and the CI matrix,
and a vX.0 tag is cut so version-pinned readers can self-serve.
- Modern C# Language Features: File-scoped namespaces, nullable reference types, and target-typed new expressions
- Improved Architecture: Interface-based design following SOLID principles
- Enhanced HTTP Implementation: Using modern patterns with
GetFromJsonAsync<T>()and improved error handling - Thread Safety: Synchronized cache access using SemaphoreSlim
- Comprehensive Test Suite: Complete test coverage with xUnit and Moq
- Decorator Pattern: Properly implemented DI registration for the caching service
- User A makes a request to our web service
- In-memory cache doesn't have a value in place, it enters into lock state and makes a request to the Users Service
- User B makes a request to our web service and waits till the lock is released
- This way, we can reduce the number of calls being made to the external web service. returns the response to our web service and the value is cached
- Lock is released, User A gets the response
- User B enters the lock and the cache provides the value (as long it's not expired)
- User B gets the response
InMemoryCachingSample/ # Main application
├── Infrastructure/ # Core infrastructure components
│ ├── CacheProvider.cs # IMemoryCache wrapper
│ └── HttpClient.cs # HTTP client implementation
├── Services/ # Business logic services
│ ├── CachedUserService.cs # Caching decorator for user service
│ ├── CacheService.cs # Cache management service
│ └── UsersService.cs # User data service
└── Utils/ # Utilities
└── CacheKeys.cs # Cache key constants
InMemoryCachingSample.Tests/ # Test project
├── CachedUserServiceTests.cs # Tests for caching decorator
├── CacheProviderTests.cs # Tests for cache provider
├── CacheServiceTests.cs # Tests for cache service
└── HttpClientTests.cs # Tests for HTTP client
- .NET 8, 9, and 10 SDKs to build all target frameworks (or build a single one with
dotnet build --framework net10.0)
# Clone the repository
git clone https://github.com/sahansera/InMemoryCacheNetCore.git
# Navigate to the project directory
cd InMemoryCacheNetCore
# Build the project
dotnet build
# Run the application
dotnet run --project InMemoryCachingSample/InMemoryCachingSample.csproj --framework net10.0
# Run the tests
dotnet testHaving any issues or troubles getting started? Get in touch with me
Has this Project helped you learn something new? or helped you at work? Please consider giving a ⭐️ if this project helped you!
Please share this Repository within your developer community, if you think that this would make a difference! Cheers.
PRs are welcome! Thank you
