Created
April 26, 2019 08:29
-
-
Save rikbosch/4afc5f7bb00bfab3d02c5995516efc70 to your computer and use it in GitHub Desktop.
AdoNetJsonStorageProvider for Orleans, allowing custom jsonserializer settings
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Reflection; | |
using System.Threading.Tasks; | |
using Microsoft.Extensions.DependencyInjection; | |
using Newtonsoft.Json; | |
using Newtonsoft.Json.Serialization; | |
using Orleans; | |
using Orleans.Providers; | |
using Orleans.Runtime; | |
using Orleans.Serialization; | |
using Orleans.Storage; | |
namespace Ao.Shared.Grains.StorageProviders | |
{ | |
public class PrivateSetterCamelCasePropertyNamesContractResolver : CamelCasePropertyNamesContractResolver | |
{ | |
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) | |
{ | |
var jProperty = base.CreateProperty(member, memberSerialization); | |
if (jProperty.Writable) | |
return jProperty; | |
jProperty.Writable = IsPropertyWithSetter(member); | |
return jProperty; | |
} | |
static bool IsPropertyWithSetter(MemberInfo member) | |
{ | |
var property = member as PropertyInfo; | |
return property?.GetSetMethod(true) != null; | |
} | |
} | |
/// <summary> | |
/// Custom storage provider which wraps AdoNetStorageProvider | |
/// Allowing custom json serializer settings | |
/// </summary> | |
public class AdoNetJsonStorageProvider : IStorageProvider | |
{ | |
private readonly AdoNetStorageProvider _inner; | |
public AdoNetJsonStorageProvider(AdoNetStorageProvider inner) | |
{ | |
_inner = inner ?? throw new ArgumentNullException(nameof(inner)); | |
} | |
public Logger Log => _inner.Log; | |
public string Name => _inner.Name; | |
public Task ClearStateAsync(string grainType, GrainReference grainReference, IGrainState grainState) => _inner.ClearStateAsync(grainType, grainReference, grainState); | |
public Task Close() => _inner.Close(); | |
public async Task Init(string name, IProviderRuntime providerRuntime, IProviderConfiguration config) | |
{ | |
await _inner.Init(name, providerRuntime, config); | |
// replace serialization picker with custom one | |
// and implement IStorageDeserializer with private setter support | |
// this is how orleans currently configures the json serializer settings for storage | |
var serializationManager = providerRuntime.ServiceProvider.GetService<SerializationManager>(); | |
var jsonSerializerSettings = OrleansJsonSerializer.UpdateSerializerSettings(OrleansJsonSerializer.GetDefaultSerializerSettings(serializationManager, providerRuntime.GrainFactory), config); | |
var jsonDeserializerSettings = OrleansJsonSerializer.UpdateSerializerSettings(OrleansJsonSerializer.GetDefaultSerializerSettings(serializationManager, providerRuntime.GrainFactory), config); | |
// we want to use a custom contractresolver | |
// when deserializing | |
jsonDeserializerSettings.ContractResolver = new PrivateSetterCamelCasePropertyNamesContractResolver(); | |
_inner.StorageSerializationPicker = new DefaultRelationalStoragePicker( | |
new[] { new OrleansStorageDefaultJsonDeserializer(jsonDeserializerSettings, null) }, | |
new[] { new OrleansStorageDefaultJsonSerializer(jsonSerializerSettings, null) } | |
); | |
} | |
public Task ReadStateAsync(string grainType, GrainReference grainReference, IGrainState grainState) => _inner.ReadStateAsync(grainType, grainReference, grainState); | |
public Task WriteStateAsync(string grainType, GrainReference grainReference, IGrainState grainState) => _inner.WriteStateAsync(grainType, grainReference, grainState); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment