Skip to content

Using Class version

Jon P Smith edited this page Oct 14, 2022 · 6 revisions

The FileStore distributed cache version known as Class inherits the String version class and then adds some extra methods that allows you to store data in a class. This is useful when you want to add a group of different data together. I personally need this as I want to store the sharding information in my AuthPermissions.AspNetCore library that helps developers to create multi-tenant applications.

This sounds complex, but actually its pretty easy to implement because of .NET's System.Text.Json library. What the extra features do is to convert your class into a json string and then call the String version's Set / SetAsync to store it. And to get back your class the method turns that json string back to a class.

The Class FileStore cache extra methods for saving / reading are:

Type Method names
Read a class cache entry GetClass(string key) / GetClassAsync(string key)
Set a class cache entry SetClass(string key, T value,...) / SetClassAsync(string key, T value,...)
Set many class cache entries SetManyClass(List<KeyValuePair<string, T>> manyEntries...)
SetManyClassAsync(List<KeyValuePair<string, T>> manyEntries...)
Get class from string GetClassFromString(string? jsonString)

The important thing to understand that the cache does not hold the class type in the cache. It is up to you to use the same type on the GetClass as you used in the SetClass method. If you get this wrong you won't get an exception, but the properties that don't match aren't filled in.

Also the class must fit the method's where clause, see the definition of the GetClass method below, but it applies all the extra Class methods.

T? GetClass<T>(string key) where T : class, new()

OTHER NOTES on the Class FileStore cache version

  • It also includes all the String version methods as well.
  • It has the UnsafeRelaxedJsonEscaping json encode by default, because it makes the json string smaller - see this section of the Tips on making your cache fast document.

Example of using the FileStore cache Class version

Once you have registered the FileStore cache (see Registering FileStore Cache) setting the WhichVersion to FileStoreCacheVersions.Class then the Class service is registered against the IDistributedFileStoreCacheClass interface as a singleton.

For this example (taken from my Unit Tests shows how you might use these methods. The examples will use the following class

public class JsonClass1
{
    public int MyInt { get; set; }
    public string MyString { get; set; }
}

And the _fsCache is set via .NET's dependency injection, as shown below:

private readonly IDistributedOptionsCacheString _fsCache;

public HomeController(IDistributedOptionsCacheString fsCache)
{
        _fsCache = fsCache;
} 

// rest of the controller left out

SetClass example

_fsCache.SetClass("test", new JsonClass1{MyInt = 1, MyString = "Hello"});

This would set the string on the cache with key "test" would look like this in the cache

"{\"MyInt\":1,\"MyString\":\"Hello\"}"

SetMany example

_fsCache.SetManyClass(new List<KeyValuePair<string, JsonClass1>>
{
    new("test1", new JsonClass1 { MyInt = 1, MyString = "Hello" }),
    new("test2", new JsonClass1 { MyInt = 2, MyString = "Goodbye" })
});

GetClass example

var jsonClass1 = _fsCache.GetClass<JsonClass1>("test");

Note in this case you have to define the type of the class you want the json to deserialized to. As mentioned already, its up to you to use the same class type as the SetClass / SetClassAsync used.

GetClassFromString example

Sometimes its quicker to load ALL the cache entries (Get takes ~25 ns, GetAllKeyValues takes ~85 ns. so if you need to look at four or more entries GetAllKeyValues is quicker). But then you need to use the GetClassFromString<T> method to return the the class.

var allValuesDict = _fsCache.GetAllKeyValues();
var jsonClass1 = _fsCache.GetClassFromString<JsonClass1>(allValuesDict["test"]);