アプリケーションデータを保存するためのKey-Valueストアライブラリー(for .NET Standard 2.0)
.NET Standard 2.0に対応している環境なら動作するはずです。
- .NET Framework
- .NET Core
- Xamarin.Android
- Xamarin.iOS
- SharedProperty
- SharedProperty.Serializer.SpanJson
- SerializerにSpanJsonを使う場合に必要
- SharedProperty.Serializer.Utf8Json
- SerializerにUtf8Jsonを使う場合に必要
- SharedProperty.Serializer.SystemTextJson
- SerializerにSystem.Text.Jsonを使う場合に必要
var sharedDictionary = new SharedDictionary(Utf8JsonSerializer.Default, FileStorage.Default, null);
SharedDictionaryは三つの引数があります。
- ISerializer
- Json形式にSerialize, Deserializeするのに必要
- IStorage
- ストレージへ保存するのに必要
- IConverter
- ストレージ保存時、難読化や暗号化するために利用
ストレージに保存されている値を利用するには必ずストレージから読み取る必要があります。
await sharedDictionary.LoadFromStorageAsync();
また、ストレージに保存する際は必ずストレージに書き込む必要があります。
await sharedDictionary.SaveToStorageAsync();
値を設定するにはSetProperty
メソッドを利用します。
sharedDictionary.SetProperty("text", "sssss");
sharedDictionary.SetProperty("number", 1234);
sharedDictionary.SetProperty("data", new Data());
sharedDictionary.SetProperty("list", new List<int> { 1, 2, 3, 4 });
コレクションやユーザー定義型なども利用できますが、各Serializerが利用しているJsonライブラリーによって制限を受けます。
値を取得するにはGetPropety
メソッドまたはTryGetProperty
メソッドを利用します。
WriteLine(sharedDictionary.GetProperty<string>("text"));
WriteLine(sharedDictionary.GetProperty<int>("number"));
WriteLine(sharedDictionary.GetProperty<Data>("data"));
WriteLine(sharedDictionary.GetProperty<List<int>>("list").Count);
現在、SharedPropertyは以下の二つのSerializerを用意しています。
- SharedProperty.Serializer.Utf8Json
- SharedProperty.Serializer.SpanJson
- SharedProperty.Serializer.SystemTextJson
.NET Standard向けの高速なJsonSerializerであるUtf8Jsonを使用することができます。
SharedDictionaryへの設定には、Utf8JsonSerializer.Default
を使用するかUtf8JsonSerializer
のインスタンスを作成してください。
各設定値のSerialize/DeserializeはUtf8Jsonが解決します。
.NET Core 2.1向けの高速なJsonSerializerであるSpanJsonを使用することができます。 SpanJsonではUTF-16にも対応していますが速度が遅くなるため、UTF-8のみのサポートとしています。
SharedDicitionaryへの設定には、SpanJsonSerializer.Default
を使用するか、SpanJsonSerializer.Create
メソッドを使用するなどしてSpanJsonSerializer
のインスタンスを作成してください。
各設定値のSerialize/DeserializeはSpanJsonが解決します。
.NET Standard向けの高速なJsonSerializerであるSystem.Text.Jsonを使用することができます。
SharedDictionaryへの設定には、SystemTextJsonSerializer.Default
を使用するかSystemTextJsonSerializer
のインスタンスを作成してください。
各設定値のSerialize/DeserializeはSystem.Text.Jsonが解決します。
SharedPropertyは二つのJson形式を用意しています。
- SerializeMode.ShortObject
- 不要な文字を排除し、サイズを減らした形式です。人間が編集するには難しいかもしれません。
- SerializeMode.LargeObject
- 通常のJsonデータに合わせた形式です。人間が編集する可能性があるならば、こちらの形式がいいかもしれません。
デフォルト値ではSerializeMode.ShortObjectが設定されています。
.NET Core 2.1向けアプリケーションでは、どちらのSerializerを利用するか悩むかもしれません。 以下のベンチマークが参考になります。
BenchmarkDotNet=v0.11.5, OS=Windows 10.0.18362
Intel Core i7-6700 CPU 3.40GHz (Skylake), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=3.0.100
[Host] : .NET Core 3.0.0 (CoreCLR 4.700.19.46205, CoreFX 4.700.19.46214), 64bit RyuJIT
Core : .NET Core 3.0.0 (CoreCLR 4.700.19.46205, CoreFX 4.700.19.46214), 64bit RyuJIT
Job=Core Runtime=Core
Method | Mean | Error | StdDev | Median | Min | Max | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|---|
ShortUtf8JsonSerialize | 920.3 ns | 23.433 ns | 68.726 ns | 883.2 ns | 842.8 ns | 1,030.2 ns | 0.2041 | - | - | 856 B |
LargeUtf8JsonSerialize | 1,178.5 ns | 55.216 ns | 65.731 ns | 1,147.1 ns | 1,118.8 ns | 1,308.9 ns | 0.0916 | - | - | 384 B |
ShortSpanJsonSerialize | 771.4 ns | 21.177 ns | 62.441 ns | 733.0 ns | 706.6 ns | 967.8 ns | 0.0763 | - | - | 320 B |
LargeSpanJsonSerialize | 1,383.7 ns | 34.000 ns | 100.250 ns | 1,432.0 ns | 1,258.5 ns | 1,675.9 ns | 0.0916 | - | - | 384 B |
ShortSystemTextJsonSerialize | 1,924.4 ns | 48.249 ns | 142.263 ns | 2,008.5 ns | 1,749.4 ns | 2,325.2 ns | 0.1469 | - | - | 616 B |
LargeSystemTextJsonSerialize | 2,232.5 ns | 21.685 ns | 19.223 ns | 2,229.3 ns | 2,204.5 ns | 2,269.5 ns | 0.1602 | - | - | 680 B |
ShortUtf8JsonDeserialize | 1,774.1 ns | 52.125 ns | 152.874 ns | 1,694.3 ns | 1,612.9 ns | 2,187.1 ns | 0.2174 | - | - | 912 B |
LargeUtf8JsonDeserialize | 2,353.2 ns | 50.123 ns | 106.817 ns | 2,315.9 ns | 2,246.3 ns | 2,666.1 ns | 0.2861 | - | - | 1200 B |
ShortSpanJsonDeserialize | 1,205.5 ns | 7.795 ns | 6.910 ns | 1,204.8 ns | 1,193.6 ns | 1,216.3 ns | 0.2174 | - | - | 912 B |
LargeSpanJsonDeserialize | 1,807.0 ns | 17.712 ns | 15.702 ns | 1,804.8 ns | 1,789.5 ns | 1,842.7 ns | 0.2861 | - | - | 1200 B |
ShortSystemTextJsonDeserialize | 2,551.4 ns | 25.394 ns | 23.753 ns | 2,544.5 ns | 2,520.5 ns | 2,591.1 ns | 0.2213 | - | - | 928 B |
LargeSystemTextJsonDeserialize | 3,376.1 ns | 29.346 ns | 27.450 ns | 3,371.6 ns | 3,335.8 ns | 3,432.8 ns | 0.2899 | - | - | 1216 B |
SharedProperty.Benchmark.NETCore/SerializerBench.cs
また、二つのSerializerを混合して使用する場合は、Utf8JsonとSpanJsonの共通の機能のみを使用する必要があります。
標準ではFileStorage
とIsolatedFileStorage
を用意しています。
ファイルパスによって保存場所を指定します。exeファイルと同じディレクトリに保存したい場合などに利用してください。
アプリケーションデータを保存する場合はIsolatedFileStorage
の使用を勧めます。
Xamarinなどのクロスプラットフォームな実行環境において.NET Standardが保存ディレクトリを解決します。
そのため、ファイルの名前によって保存場所を指定します。
難読化や暗号化のために標準ではいくつかのConverterを用意しています。
難読化のためのConverterは以下のものを用意しています。
SimpleConverter.Default
AesCryptoConverter.Default
RijndaelCryptoConverter.Default
SimpleConverter.Default
は単純に文字コードを+1しているだけなので非常に高速です。ちょっとリッチな難読化をする場合はAesCryptoConverter.Default
またはRijndaelCryptoConverter.Default
を利用してください。
暗号化にはAesCryptoConverter
またはRijndaelCryptoConverter
が使用できます。
強度なセキュリティを保つには開発者は必ずアプリケーション固有の暗号鍵を使用する必要があります。
SharedDictionary
クラスはスレッドセーフではありません。複数スレッドで操作する場合は、ConcurrentSharedDictionary
クラスを使用してください。
現在、SharedPropertyでは値の取得時に暗黙的型変換が可能です。
int i = 1234;
sharedDictionary.SetProperty("number", i);
// 内部的にはintで保持されている
long l = sharedDictionary.GetProperty<long>("number")
このような、コードを書くこともできます。
しかし、パフォーマンスがいいとは言えません。また、今後削除する可能性のある機能でもあるので、正確に型指定することを推奨します。
対応している暗黙的型変換
- アップキャスト
- 共変性・反変性
- Nullable化
- 暗黙的な数値変換
- implicit operator
Utf8JsonSerializer.MigrationTypeDictionary
またはSpanJsonSerializer.MigrationTypeDictionary
またはSystemTextJsonSerializer.MigrationTypeDictionary
を使用することによって保存した値の型をマイグレーションすることが可能です。
また、同じ型でのマイグレーションはUtf8JsonまたはSpanJsonのCustomFormatterResolverとCustomFormatterを作成してください。
また、ファイル読み込み時に不明な型のデータは読み込みがスキップされます。
Xamarin.iOSではAOTのためUtf8Json.Resolvers.StandardResolver.Default
を利用するとアプリケーションがクラッシュします。
AotStandardResolver
クラスを用意していますが、ユーザー定義型はUtf8Jsonのコードジェネレーターを利用してください。
このライブラリーはMIT Licenseによって公開されています。
パッケージによって使用するライブラリが異なります。
SharedProperty.Serializer.Utf8Json
- Utf8Json : MIT Licenseによって公開されています
- System.Buffers : MIT Licenseによって公開されています
SharedProperty.Serializer.SpanJson
- SpanJson : MIT Licenseによって公開されています
SharedProperty.Serializer.SystemTextJson
- System.Text.Json : MIT Licenseによって公開されています
ベンチマークには以下のライブラリを使用しています。
- BenchmarkDotNet : MIT Licenseによって公開されています。
サンプルには以下のライブラリを使用しています。
- Utf8Json : MIT Licenseによって公開されています
- Xamarin.Forms : MIT Licenseによって公開されています。
- AndroidSupportComponents : MIT Licenseによって公開されています。