CleverCache 1.0.7

There is a newer version of this package available.
See the version list below for details.
dotnet add package CleverCache --version 1.0.7
                    
NuGet\Install-Package CleverCache -Version 1.0.7
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="CleverCache" Version="1.0.7" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="CleverCache" Version="1.0.7" />
                    
Directory.Packages.props
<PackageReference Include="CleverCache" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add CleverCache --version 1.0.7
                    
#r "nuget: CleverCache, 1.0.7"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package CleverCache@1.0.7
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=CleverCache&version=1.0.7
                    
Install as a Cake Addin
#tool nuget:?package=CleverCache&version=1.0.7
                    
Install as a Cake Tool

Setup

  1. Add the services:

    builder.Services.AddCleverCache();
    
  2. Ensure the interceptor is registered on your database context in any of the following ways:

    // The interceptor interface if you have no other interceptors
    public class AppDbContext(IInterceptor cleverCacheInterceptor) : DbContext()
    {
        private readonly IInterceptor _cleverCacheInterceptor = cleverCacheInterceptor;
    
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.AddInterceptors(new IInterceptor[] { cleverCacheInterceptor });
        }
    }
    

    or

    // The interceptor array if you are already using interceptors
    public class AppDbContext(IInterceptor[] interceptors) : DbContext()
    {
        private readonly IInterceptor[] _interceptors= interceptors;
    
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.AddInterceptors(interceptors);
        }
    }
    

    or the concrete class

    // The interceptor interface if you have no other interceptors
    public class AppDbContext(CleverCacheInterceptor cleverCacheInterceptor) : DbContext()
    {
        private readonly CleverCacheInterceptor _cleverCacheInterceptor = cleverCacheInterceptor;
    
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.AddInterceptors(new IInterceptor[] { cleverCacheInterceptor });
        }
    }
    
  3. Add the using to your app specifying the db context you are tracking:

    app.UseCleverCache<AppDbContext>();
    

Usage

You create cache in the same way you would when using MemoryCache but specify an additional type parameter like this to associate a given type with a cache key:

    var myItem = await cache.GetOrCreateAsync(
	    typeof(MyEntityType),
	    cacheKey,
	    _ => 
	    {
		    //return <Do real query for data>;
	    }
    ) ?? [];

The interceptor tracks when any instance of MyEntityType is added, changed or deleted and will clear all cache keys associated with that type

Dependent Caches

Often you have information in a cache entry that contains data from multiple entity types and the caches needs to be refreshed if ANY of the types changes not just the primary object.

You can create these association manually on a type by type basis by calling:

cache.AddKeyToType(type, key);

or more succinctly:

cache.AddKeyToType<OtherType>(key);

You can also do multiple types in one call by calling:

cache.AddKeyToTypes(arrayOfTypes, key);

You can also do it by specifying an array of types when calling any of the create methods.

However this can be tiresome and result in repetitive code. If you know you often need to do this for a given entity you configure it globally via an attribute on the class like this:

[DependantCaches([typeof(ThingTwo),typeof(ThingThree)])]
public class ThingOne 
{
    public ThingTwo Two {get; set;};
    public ThingThree Three {get; set;};
}

public class ThingTwo;
public class ThingThree;

This will automatically register any keys for ThingOne with ThingTwo and ThingThree so changes to any object of these types will clear the cache key. You can also reverse these mapping by using reverse: true in the attribute. This will register ThingTwo and ThingThree with ThingOne

Auto caching mediatr queries

This is a really powerful tool that enables you to quickly add caching to your mediatr queries without any changes to your handlers.

Add the following to your mediatr setup:

services.AddMediatR(cfg =>
{
	// Other config you may have
	cfg.AddCleverCache(); // Registers the mediatr pipeline behaviour
});

Then simply add the following attribute to any query you want to cache, specifing the type(s) you want the cache for:

[AutoCache([typeof(MyEntityType)])]
public record MyQuery : IRequest;

This uses the mediatr request as the cache key so you can use the same query with different parameters and it will cache each one separately.

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.