Aiursoft InMemoryKvDb is a lightweight, thread-safe, in-memory key-value database with support for automatic Least Recently Used (LRU) cache eviction. It allows for efficient storage and retrieval of key-value pairs while preventing unbounded memory usage by leveraging configurable LRU eviction policies.
This library is ideal for scenarios where you need an in-memory cache that automatically discards the least recently accessed items, such as storing temporary user data, caching API responses, or handling in-memory operations for temporary data processing, without worrying about potential memory overflows.
The traditional way to create an In-Memory Key-Value Database in C# is:
public class InMemoryDatabase : ISingletonDependency
{
private ConcurrentDictionary<Guid, Player> Players { get; } = new();
public Player GetOrAddPlayer(Guid id)
{
lock (Players)
{
return Players.GetOrAdd(id, _ => new Player(id)
{
NickName = "Anonymous " + new Random().Next(1000, 9999)
});
}
}
}
However, if a hacker keeps calling GetOrAddPlayer
with a new Guid
, the Players
dictionary will grow infinitely. And cause you OutOfMemoryException
.
First, install Aiursoft.InMemoryKvDb
to your ASP.NET Core project from nuget.org:
dotnet add package Aiursoft.InMemoryKvDb
Add the service to your IServiceCollection
in Startup.cs
(or Program.cs
in .NET 6 and later):
AddNamedLruMemoryStore<T, TK>
AddNamedLruMemoryStoreManualCreate<T, TK>
AddLruMemoryStore<T, TK>
AddLruMemoryStoreManualCreate<T, TK>
-
Named vs. Non-Named Stores:
- Named stores (
AddNamedLruMemoryStore
andAddNamedLruMemoryStoreManualCreate
) allow you to create multiple isolated caches identified by unique names, suitable for scenarios where you need separate caches within the same application. - Non-named stores (
AddLruMemoryStore
andAddLruMemoryStoreManualCreate
) are simpler and provide a single cache instance.
- Named stores (
-
Automatic vs. Manual Key-Value Creation:
- Automatic creation (
AddLruMemoryStore
andAddNamedLruMemoryStore
) uses anonNotFound
function to generate values for missing keys automatically. - Manual creation (
AddLruMemoryStoreManualCreate
andAddNamedLruMemoryStoreManualCreate
) requires explicit value creation when adding items, providing greater control over how values are added to the cache.
- Automatic creation (
var services = new ServiceCollection();
services.AddNamedLruMemoryStore<Player, Guid>(
id => new Player(id, "GeneratedPlayer"),
maxCachedItemsCount: 5);
var serviceProvider = services.BuildServiceProvider();
var namedProvider = serviceProvider.GetService<NamedLruMemoryStoreProvider<Player, Guid>>();
var store = namedProvider.GetStore("player-store");
var player = store.GetOrAdd(Guid.NewGuid());
var services = new ServiceCollection();
services.AddNamedLruMemoryStoreManualCreate<Player, Guid>(maxCachedItemsCount: 5);
var serviceProvider = services.BuildServiceProvider();
var namedProvider = serviceProvider.GetService<NamedLruMemoryStoreManualCreatedProvider<Player, Guid>>();
var store = namedProvider.GetStore("player-store");
var player = store.GetOrAdd(Guid.NewGuid(), id => new Player(id, "ManualPlayer"));
var services = new ServiceCollection();
services.AddLruMemoryStore<Player, Guid>(
id => new Player(id, "GeneratedPlayer"),
maxCachedItemsCount: 3);
var serviceProvider = services.BuildServiceProvider();
var store = serviceProvider.GetService<LruMemoryStore<Player, Guid>>();
var player = store.GetOrAdd(Guid.NewGuid());
var services = new ServiceCollection();
services.AddLruMemoryStoreManualCreate<Player, Guid>(maxCachedItemsCount: 3);
var serviceProvider = services.BuildServiceProvider();
var store = serviceProvider.GetService<LruMemoryStoreManualCreated<Player, Guid>>();
var player = store.GetOrAdd(Guid.NewGuid(), id => new Player(id, "ManualPlayer"));
Choose the appropriate method based on whether you need isolated named stores and whether you prefer automatic or manual value creation.
Contributions are welcome! Please open an issue or submit a pull request for any feature requests, bug fixes, or other improvements.