5 Implementing cache serializers
martincostello редактировал(а) эту страницу 2023-09-28 13:52:17 +01:00
Этот файл содержит невидимые символы Юникода!

Этот файл содержит невидимые символы Юникода, которые могут быть отображены не так, как показано ниже. Если это намеренно, можете спокойно проигнорировать это предупреждение. Используйте кнопку Экранировать, чтобы показать скрытые символы.

Этот файл содержит неоднозначные символы Юникода, которые могут быть перепутаны с другими в текущей локали. Если это намеренно, можете спокойно проигнорировать это предупреждение. Используйте кнопку Экранировать, чтобы подсветить эти символы.

Cache: Implementing serializers

This documentation describes the previous Polly v7 API. If you are using the new v8 API, please refer to pollydocs.org.

The Polly.Caching namespace provides an ICacheItemSerializer<TResult, TSerialized> interface.

Implementations of this interface allow you to serialize items for placing in the cache, and deserialize again on retrieving from cache.

Creating serializers

The interface ICacheItemSerializer<TResult, TSerialized> is very simple to fulfil:

public interface ICacheItemSerializer<TResult, TSerialized>
{
    TSerialized Serialize(TResult objectToSerialize);
    TResult Deserialize(TSerialized objectToDeserialize);
}

Why do we need serializers?

Some cache providers (such as Redis) store most items as specific types (eg string or byte[]), requiring you to serialize more complex types to those. For example, for Redis you might have a:

RedisCacheProvider<string>: ISyncCacheProvider<string>, IAsyncCacheProvider<string>

The above RedisCacheProvider<string> (as is) would only be usable in CachePolicy<string>. To use the cache for other result types, you might implement (for example using Newtonsoft.Json):

JsonSerializer<TResult> : ICacheItemSerializer<TResult, string>
{
    string Serialize(TResult objectToSerialize);
    TResult Deserialize(string objectToDeserialize);
}

Note: Redis and NewtonSoft.Json are referenced above to provide an easy-to-grok example of why you might need to implement a serializer. For these specific solutions, however, Polly already provides:

Using a serializer with the Polly CachePolicy

An in-built extension method in Polly, .WithSerializer<TResult, TSerialized>(...) allows you to bridge from the native TResult of the execution to the TSerialized type of serialized objects in the cache.

ISyncCacheProvider<TSerialized>.WithSerializer<TResult, TSerialized>(...) returns an ISyncCacheProvider<TResult>, the type needed in order to configure CachePolicy<TResult>. For example:

ISyncCacheProvider<string> redisCacheProvider = ... // configured earlier
ICacheItemSerializer<TResult, string> jsonSerializer = ... // configured earlier

CachePolicy<TResult> cache = Policy.Cache<TResult>(
    redisCacheProvider.WithSerializer(jsonSerializer),
    TimeSpan.FromMinutes(5) /* for example; see https://github.com/App-vNext/Polly/wiki/Cache#syntax for deeper options */
);

The above examples are based around serializing to string using Newtonsoft.Json as this is one of the most commonly understood serialization approaches. However, it is far from the only option. For a fuller overview of serialization options available, see the Microsoft Patterns-and-Practices article on Caching, section Serialization considerations.

Other users for ICacheItemSerializer

Serialization/deserialization is just a form of manipulating the content in and out of cache. It can therefore also be re-purposed for other uses, such as removing personally-recognisable information or encrypting information on the way in and out of cache.

Community contributions

Community contributions of new third-party serializers for Polly are welcome. Let us know, and we can make new providers available to the wider Polly community via Polly-Contrib. The contrib contains a blank template repo referencing Polly, with build, as a suitable starting poitn for a serializer implementation.