Serialization configuration in Orleans
The configuration of serialization in Orleans is a crucial part of the overall system design. While Orleans provides reasonable defaults, you can configure serialization to suit your apps' needs. For sending data between hosts, Orleans.Serialization supports delegating to other serializers, such as Newtonsoft.Json and System.Text.Json. You can add support for other serializers by following the pattern set by those implementations. For grain storage it's best to use IGrainStorageSerializer to configure a custom serializer.
Configure Orleans to use Newtonsoft.Json
To configure Orleans to serialize certain types using Newtonsoft.Json
, you must first reference the Microsoft.Orleans.Serialization.NewtonsoftJson NuGet package. Then, configure the serializer, specifying which types it will be responsible for. In the following example, we will specify that the Newtonsoft.Json
serializer will be responsible for all types in the Example.Namespace
namespace.
siloBuilder.Services.AddSerializer(serializerBuilder =>
{
serializerBuilder.AddNewtonsoftJsonSerializer(
isSupported: type => type.Namespace.StartsWith("Example.Namespace"));
});
In the preceding example, the call to AddNewtonsoftJsonSerializer adds support for serializing and deserializing values using Newtonsoft.Json.JsonSerializer
. Similar configuration must be performed on all clients that need to handle those types.
For types that are marked with GenerateSerializerAttribute), Orleans will prefer the generated serializer over the Newtonsoft.Json
serializer.
Configure Orleans to use System.Text.Json
Alternatively, to configure Orleans to use System.Text.Json
to serialize your types, you reference the Microsoft.Orleans.Serialization.SystemTextJson NuGet package. Then, configure the serializer, specifying which types it will be responsible for. In the following example, we will specify that the System.Text.Json
serializer will be responsible for all types in the Example.Namespace
namespace.
- Install the Microsoft.Orleans.Serialization.SystemTextJson NuGet package.
- Configure the serializer using the AddJsonSerializer method.
Consider the following example when interacting with the ISiloBuilder:
siloBuilder.Services.AddSerializer(serializerBuilder =>
{
serializerBuilder.AddJsonSerializer(
isSupported: type => type.Namespace.StartsWith("Example.Namespace"));
});
External serializer providers
It's important to ensure that serialization configuration is identical on all clients and silos. If configurations are inconsistent, serialization errors may occur.
Serialization providers that implement IExternalSerializer
can be specified using the SerializationProviderOptions.SerializationProviders property of ClientConfiguration and GlobalConfiguration in code:
// Client configuration
var clientConfiguration = new ClientConfiguration();
clientConfiguration.SerializationProviders.Add(
typeof(FantasticSerializer).GetTypeInfo());
// Global configuration
var globalConfiguration = new GlobalConfiguration();
globalConfiguration.SerializationProviders.Add(
typeof(FantasticSerializer).GetTypeInfo());
Alternatively, they can be specified in XML configuration under the <SerializationProviders />
property of <Messaging>
:
<Messaging>
<SerializationProviders>
<Provider type="GreatCompany.FantasticSerializer, GreatCompany.SerializerAssembly" />
</SerializationProviders>
</Messaging>
In both cases, multiple providers can be configured. The collection is ordered, meaning that if a provider which can serialize types A
and B
is specified before a provider which can only serialize type B
, then the latter provider will not be used.