Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ObjectStorage enhancements #4102

Merged
57 commits merged into from
Jul 29, 2021
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
223437c
Deprecated existing ObjectStorage classes and migrated some to the *.…
shweaver-MSFT Jul 8, 2021
5629f4d
Code style tweak
shweaver-MSFT Jul 8, 2021
c26c3f1
Updated headers and bad namespace
shweaver-MSFT Jul 8, 2021
5b26ce8
Merge branch 'main' into shweaver/storage-helpers
shweaver-MSFT Jul 8, 2021
41da215
Fixed possible null reference warnings
shweaver-MSFT Jul 8, 2021
8948003
Merge branch 'shweaver/storage-helpers' of https://github.com/windows…
shweaver-MSFT Jul 8, 2021
e809fab
Fixed another potential null
shweaver-MSFT Jul 8, 2021
4eaceec
Updated storage related unit tests
shweaver-MSFT Jul 9, 2021
be6555d
Updated ambiguous references in comments
shweaver-MSFT Jul 9, 2021
d9e43fb
Updated ObjectStorage references in samples
shweaver-MSFT Jul 12, 2021
c6184ed
Update Microsoft.Toolkit.Uwp/Helpers/ObjectStorage/IObjectSerializer.cs
shweaver-MSFT Jul 13, 2021
870c85f
Update Microsoft.Toolkit.Uwp/Helpers/ObjectStorage/SystemSerializer.cs
shweaver-MSFT Jul 13, 2021
e36c955
PR updates
shweaver-MSFT Jul 14, 2021
09cf213
Merge branch 'shweaver/storage-helpers' of https://github.com/windows…
shweaver-MSFT Jul 14, 2021
7edade1
Renamed SaveFile/FolderAsync to CreateFile/FolderAsync
shweaver-MSFT Jul 14, 2021
bf97b45
Readded SaveFileAsync to match previous implementation
shweaver-MSFT Jul 14, 2021
cf294f2
Merge branch 'main' into shweaver/storage-helpers
shweaver-MSFT Jul 16, 2021
5707c6d
Fixed typo in IObjectStorageHelper. Updated var name to be more accur…
shweaver-MSFT Jul 16, 2021
5927987
Merge branch 'main' into shweaver/storage-helpers
shweaver-MSFT Jul 16, 2021
f70e369
Updated storage var names to be consistent across solution
shweaver-MSFT Jul 19, 2021
fd8a1fd
Merge branch 'shweaver/storage-helpers' of https://github.com/windows…
shweaver-MSFT Jul 19, 2021
1f53d9a
Making serializer optional for ApplicationDataStorageHelper and defau…
shweaver-MSFT Jul 19, 2021
8140bff
Added support for the LocalCacheFolder to validate extensibility of A…
shweaver-MSFT Jul 19, 2021
949e820
Merge branch 'main' into shweaver/storage-helpers
shweaver-MSFT Jul 19, 2021
ddcf8c2
Adding license header
shweaver-MSFT Jul 19, 2021
28ee577
Merge branch 'shweaver/storage-helpers' of https://github.com/windows…
shweaver-MSFT Jul 19, 2021
655caf6
Whitespace fix
shweaver-MSFT Jul 19, 2021
1869039
Merge branch 'main' into shweaver/storage-helpers
shweaver-MSFT Jul 20, 2021
a0e4e49
Merge branch 'main' into shweaver/storage-helpers
shweaver-MSFT Jul 21, 2021
8476f70
PR updates
shweaver-MSFT Jul 21, 2021
e921d89
Updated ISettingsStorageHelper references
shweaver-MSFT Jul 22, 2021
57d872b
Merge branch 'shweaver/storage-helpers' of https://github.com/windows…
shweaver-MSFT Jul 22, 2021
3e083a3
Merge branch 'main' into shweaver/storage-helpers
shweaver-MSFT Jul 22, 2021
e61c0cd
Update Microsoft.Toolkit/Helpers/ObjectStorage/IFileStorageHelper.cs
shweaver-MSFT Jul 22, 2021
0e414ec
Removed default param from ISettingsStorageHelper.Read method and upd…
shweaver-MSFT Jul 22, 2021
11cab80
Merge branch 'shweaver/storage-helpers' of https://github.com/windows…
shweaver-MSFT Jul 22, 2021
51d58cd
Updated JsonObjectSerializer and SystemTextJsonSerializer in Uwp test…
shweaver-MSFT Jul 22, 2021
522d55b
Merge branch 'main' into shweaver/storage-helpers
shweaver-MSFT Jul 22, 2021
27cae2e
Added extension methods for ISettingsStorageHelper
shweaver-MSFT Jul 22, 2021
5fd25ce
Merge branch 'shweaver/storage-helpers' of https://github.com/windows…
shweaver-MSFT Jul 22, 2021
22068f1
Merge branch 'main' into shweaver/storage-helpers
shweaver-MSFT Jul 22, 2021
9504193
Merge branch 'main' into shweaver/storage-helpers
michael-hawker Jul 23, 2021
3f3868a
Merge branch 'main' into shweaver/storage-helpers
shweaver-MSFT Jul 23, 2021
13c3e2f
Update Microsoft.Toolkit/Helpers/ObjectStorage/ISettingsStorageHelper.cs
shweaver-MSFT Jul 26, 2021
b472cc8
PR updates
shweaver-MSFT Jul 26, 2021
c36db17
Merge branch 'shweaver/storage-helpers' of https://github.com/windows…
shweaver-MSFT Jul 26, 2021
82c2ba3
PR updates
shweaver-MSFT Jul 26, 2021
f3080d0
Merge branch 'main' into shweaver/storage-helpers
shweaver-MSFT Jul 26, 2021
dc218aa
The ever important file header!
shweaver-MSFT Jul 26, 2021
93efeaf
Merge branch 'shweaver/storage-helpers' of https://github.com/windows…
shweaver-MSFT Jul 26, 2021
f4207ea
Added Obsolete attributes to old storage helper tests
shweaver-MSFT Jul 27, 2021
331f7dd
Comment cref updates in test app
shweaver-MSFT Jul 27, 2021
11d1a5e
PR updates
shweaver-MSFT Jul 28, 2021
b551d43
Update Microsoft.Toolkit/Extensions/ISettingsStorageHelperExtensions.cs
shweaver-MSFT Jul 28, 2021
e65332b
Merge branch 'main' into shweaver/storage-helpers
shweaver-MSFT Jul 28, 2021
76aa847
Update Microsoft.Toolkit.Uwp/Helpers/ObjectStorage/ApplicationDataSto…
shweaver-MSFT Jul 29, 2021
b0a33c5
Fixed warnings in ObjectStorage classes
shweaver-MSFT Jul 29, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ public string DesiredLang
/// <summary>
/// The Local Storage Helper.
/// </summary>
private LocalObjectStorageHelper storage = new LocalObjectStorageHelper(new SystemSerializer());
private ApplicationDataStorageHelper storage = ApplicationDataStorageHelper.GetCurrent(new Toolkit.Helpers.SystemSerializer());

/// <summary>
/// DocFX note types and styling info, keyed by identifier.
Expand Down
2 changes: 1 addition & 1 deletion Microsoft.Toolkit.Uwp.SampleApp/Models/Sample.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public class Sample

public static async void EnsureCacheLatest()
{
var settingsStorage = new LocalObjectStorageHelper(new SystemSerializer());
var settingsStorage = ApplicationDataStorageHelper.GetCurrent(new Toolkit.Helpers.SystemSerializer());

var onlineDocsSHA = await GetDocsSHA();
var cacheSHA = settingsStorage.Read<string>(_cacheSHAKey);
Expand Down
2 changes: 1 addition & 1 deletion Microsoft.Toolkit.Uwp.SampleApp/Models/Samples.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public static class Samples
private static SemaphoreSlim _semaphore = new SemaphoreSlim(1);

private static LinkedList<Sample> _recentSamples;
private static LocalObjectStorageHelper _localObjectStorageHelper = new LocalObjectStorageHelper(new SystemSerializer());
private static ApplicationDataStorageHelper _localObjectStorageHelper = ApplicationDataStorageHelper.GetCurrent(new Toolkit.Helpers.SystemSerializer());
shweaver-MSFT marked this conversation as resolved.
Show resolved Hide resolved

public static async Task<SampleCategory> GetCategoryBySample(Sample sample)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
var localObjectStorageHelper = new LocalObjectStorageHelper();
var roamingObjectStorageHelper = new RoamingObjectStorageHelper();
ApplicationDataStorageHelper appDataStorageHelper = ApplicationDataStorageHelper.GetCurrent(new Toolkit.Helpers.SystemSerializer());

// Read and Save with simple objects
string keySimpleObject = "simple";
string result = localObjectStorageHelper.Read<string>(keySimpleObject);
localObjectStorageHelper.Save(keySimpleObject, 47);
string result = appDataStorageHelper.Read<string>(keySimpleObject);
appDataStorageHelper.Save(keySimpleObject, 47);

// Read and Save with complex/large objects
string keyLargeObject = "large";
var result = localObjectStorageHelper.ReadFileAsync<MyLargeObject>(keyLargeObject);
string complexObjectKey = "complexObject";
var complexObject = await appDataStorageHelper.ReadFileAsync<MyLargeObject>(complexObjectKey);

var o = new MyLargeObject
var myComplexObject = new MyComplexObject()
{
...
};
localObjectStorageHelper.SaveFileAsync(keySimpleObject, o);
await appDataStorageHelper.SaveFileAsync(complexObjectKey, myComplexObject);

// Complex object
public class MyLargeObject
public class MyComplexObject
{
public string MyContent { get; set; }
public List<string> MyContents { get; set; }
public List<MyLargeObject> MyObjects { get; set; }
public List<MyComplexObject> MyObjects { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Microsoft.Toolkit.Helpers;
using Microsoft.Toolkit.Uwp.Helpers;
using Windows.UI.Xaml;

namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages
{
public sealed partial class ObjectStoragePage
{
private readonly IObjectStorageHelper localStorageHelper = new LocalObjectStorageHelper(new SystemSerializer());
private readonly ISettingsStorageHelper localStorageHelper = ApplicationDataStorageHelper.GetCurrent(new Toolkit.Helpers.SystemSerializer());

public ObjectStoragePage()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Toolkit.Helpers;
using Windows.Storage;
using Windows.System;

shweaver-MSFT marked this conversation as resolved.
Show resolved Hide resolved
namespace Microsoft.Toolkit.Uwp.Helpers
{
/// <summary>
/// Storage helper for files and folders living in Windows.Storage.ApplicationData storage endpoints.
/// </summary>
public class ApplicationDataStorageHelper : IFileStorageHelper, ISettingsStorageHelper
{
/// <summary>
/// Get a new instance using ApplicationData.Current and the provided serializer.
/// </summary>
/// <param name="objectSerializer">Serializer for converting stored values.</param>
/// <returns>A new instance of ApplicationDataStorageHelper.</returns>
public static ApplicationDataStorageHelper GetCurrent(Toolkit.Helpers.IObjectSerializer objectSerializer)
{
var appData = ApplicationData.Current;
return new ApplicationDataStorageHelper(appData, objectSerializer);
}

/// <summary>
/// Get a new instance using the ApplicationData for the provided user and serializer.
/// </summary>
/// <param name="user">App data user owner.</param>
/// <param name="objectSerializer">Serializer for converting stored values.</param>
/// <returns>A new instance of ApplicationDataStorageHelper.</returns>
public static async Task<ApplicationDataStorageHelper> GetForUserAsync(User user, Toolkit.Helpers.IObjectSerializer objectSerializer)
{
var appData = await ApplicationData.GetForUserAsync(user);
return new ApplicationDataStorageHelper(appData, objectSerializer);
}

/// <summary>
/// Gets the settings container.
/// </summary>
protected ApplicationData AppData { get; private set; }

private ApplicationDataContainer DefaultSettings => AppData.LocalSettings;

private StorageFolder DefaultFolder => AppData.LocalFolder;

private readonly Toolkit.Helpers.IObjectSerializer _serializer;

/// <summary>
/// Initializes a new instance of the <see cref="ApplicationDataStorageHelper"/> class.
/// </summary>
/// <param name="appData">The data store to interact with.</param>
/// <param name="objectSerializer">Serializer for converting stored values.</param>
public ApplicationDataStorageHelper(ApplicationData appData, Toolkit.Helpers.IObjectSerializer objectSerializer)
{
AppData = appData ?? throw new ArgumentNullException(nameof(appData));
michael-hawker marked this conversation as resolved.
Show resolved Hide resolved
_serializer = objectSerializer ?? throw new ArgumentNullException(nameof(objectSerializer));
}

/// <inheritdoc />
public bool KeyExists(string key)
{
return DefaultSettings.Values.ContainsKey(key);
}

/// <inheritdoc />
public bool KeyExists(string compositeKey, string key)
{
if (KeyExists(compositeKey))
{
ApplicationDataCompositeValue composite = (ApplicationDataCompositeValue)DefaultSettings.Values[compositeKey];
if (composite != null)
{
return composite.ContainsKey(key);
}
}

return false;
}

/// <inheritdoc />
public T Read<T>(string key, T @default = default)
{
if (!DefaultSettings.Values.TryGetValue(key, out var value) || value == null)
{
return @default;
}

return _serializer.Deserialize<T>(value);
}

/// <inheritdoc />
public T Read<T>(string compositeKey, string key, T @default = default)
{
ApplicationDataCompositeValue composite = (ApplicationDataCompositeValue)DefaultSettings.Values[compositeKey];
if (composite != null)
{
string value = (string)composite[key];
if (value != null)
{
return _serializer.Deserialize<T>(value);
}
}

return @default;
}

/// <inheritdoc />
public void Save<T>(string key, T value)
{
DefaultSettings.Values[key] = _serializer.Serialize(value);
}

/// <inheritdoc />
public void Save<T>(string compositeKey, IDictionary<string, T> values)
{
if (KeyExists(compositeKey))
{
ApplicationDataCompositeValue composite = (ApplicationDataCompositeValue)DefaultSettings.Values[compositeKey];

foreach (KeyValuePair<string, T> setting in values)
{
if (composite.ContainsKey(setting.Key))
{
composite[setting.Key] = _serializer.Serialize(setting.Value);
}
else
{
composite.Add(setting.Key, _serializer.Serialize(setting.Value));
}
}
}
else
{
ApplicationDataCompositeValue composite = new ApplicationDataCompositeValue();
foreach (KeyValuePair<string, T> setting in values)
{
composite.Add(setting.Key, _serializer.Serialize(setting.Value));
}

DefaultSettings.Values[compositeKey] = composite;
}
}

/// <inheritdoc />
public void Delete(string key)
{
DefaultSettings.Values.Remove(key);
}

/// <inheritdoc />
public void Delete(string compositeKey, string key)
{
if (KeyExists(compositeKey))
{
ApplicationDataCompositeValue composite = (ApplicationDataCompositeValue)DefaultSettings.Values[compositeKey];
composite.Remove(key);
}
}

/// <inheritdoc />
public Task<bool> FileExistsAsync(string filePath)
{
return FileExistsAsync(DefaultFolder, filePath);
}

/// <inheritdoc />
public Task<T> ReadFileAsync<T>(string filePath, T @default = default)
{
return ReadFileAsync<T>(DefaultFolder, filePath, @default);
}

/// <inheritdoc />
public Task<IList<string>> ReadFolderAsync(string folderPath)
{
return ReadFolderAsync(DefaultFolder, folderPath);
}

/// <inheritdoc />
public Task SaveFileAsync<T>(string filePath, T value)
{
return SaveFileAsync<T>(DefaultFolder, filePath, value);
}

/// <inheritdoc />
public Task SaveFolderAsync(string folderPath)
{
return SaveFolderAsync(DefaultFolder, folderPath);
}

/// <inheritdoc />
public Task DeleteItemAsync(string itemPath)
{
return DeleteItemAsync(DefaultFolder, itemPath);
}

private Task<bool> FileExistsAsync(StorageFolder folder, string filePath)
{
return folder.FileExistsAsync(filePath);
}

private async Task<T> ReadFileAsync<T>(StorageFolder folder, string filePath, T @default = default)
{
string value = await StorageFileHelper.ReadTextFromFileAsync(folder, filePath);
return (value != null) ? _serializer.Deserialize<T>(value) : @default;
}

private async Task<IList<string>> ReadFolderAsync(StorageFolder folder, string folderPath)
{
var targetFolder = await folder.GetFolderAsync(folderPath);
var files = await targetFolder.GetFilesAsync();
return files.Select((f) => f.Path + f.Name).ToList();
}

private Task SaveFileAsync<T>(StorageFolder folder, string filePath, T value)
{
return StorageFileHelper.WriteTextToFileAsync(folder, _serializer.Serialize(value)?.ToString(), filePath, CreationCollisionOption.ReplaceExisting);
}

private async Task SaveFolderAsync(StorageFolder folder, string folderPath)
{
await folder.CreateFolderAsync(folderPath, CreationCollisionOption.OpenIfExists);
}

private async Task DeleteItemAsync(StorageFolder folder, string itemPath)
{
var item = await folder.GetItemAsync(itemPath);
await item.DeleteAsync();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace Microsoft.Toolkit.Uwp.Helpers
/// <summary>
/// Shared implementation of ObjectStorageHelper.
/// </summary>
[Obsolete("BaseObjectStorageHelper is deprecated and has been superceded by ApplicationDataStorageHelper.")]
public abstract class BaseObjectStorageHelper : IObjectStorageHelper
{
private readonly IObjectSerializer serializer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;

namespace Microsoft.Toolkit.Uwp.Helpers
{
/// <summary>
/// A basic serialization service.
/// </summary>
[Obsolete("IObjectSerializer has been migrated to the *.Toolikit package.")]
shweaver-MSFT marked this conversation as resolved.
Show resolved Hide resolved
public interface IObjectSerializer
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.Storage;
Expand All @@ -11,6 +12,7 @@ namespace Microsoft.Toolkit.Uwp.Helpers
/// <summary>
/// Service used to store data.
/// </summary>
[Obsolete("IObjectStorageHelper is deprecated. Please use IDictionaryStorageHelper and IFileStorageHelper interfaces instead.")]
shweaver-MSFT marked this conversation as resolved.
Show resolved Hide resolved
public interface IObjectStorageHelper
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using Windows.Storage;

namespace Microsoft.Toolkit.Uwp.Helpers
{
/// <summary>
/// Store data in the Local environment (only on the current device).
/// </summary>
[Obsolete("LocalObjectStorageHelper is deprecated and has been superceded by the ApplicationDataStorageHelper.")]
shweaver-MSFT marked this conversation as resolved.
Show resolved Hide resolved
public class LocalObjectStorageHelper : BaseObjectStorageHelper
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace Microsoft.Toolkit.Uwp.Helpers
/// A bare-bones serializer which knows how to deal with primitive types and strings only. It will store them directly based on the <see cref="ApplicationDataContainer"/> API.
/// It is recommended for more complex scenarios to implement your own <see cref="IObjectSerializer"/> based on System.Text.Json, Newtonsoft.Json, or DataContractJsonSerializer see https://aka.ms/wct/storagehelper-migration
/// </summary>
[Obsolete("SystemSerializer has been migrated to the *.Toolikit package.")]
shweaver-MSFT marked this conversation as resolved.
Show resolved Hide resolved
public class SystemSerializer : IObjectSerializer
{
/// <summary>
Expand Down
4 changes: 2 additions & 2 deletions Microsoft.Toolkit.Uwp/Helpers/SystemInformation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ namespace Microsoft.Toolkit.Uwp.Helpers
public sealed class SystemInformation
{
/// <summary>
/// The <see cref="LocalObjectStorageHelper"/> instance used to save and retrieve application settings.
/// The <see cref="ApplicationDataStorageHelper"/> instance used to save and retrieve application settings.
/// </summary>
private readonly LocalObjectStorageHelper _localObjectStorageHelper = new(new SystemSerializer());
private readonly ApplicationDataStorageHelper _localObjectStorageHelper = ApplicationDataStorageHelper.GetCurrent(new Toolkit.Helpers.SystemSerializer());

/// <summary>
/// The starting time of the current application session (since app launch or last move to foreground).
Expand Down
Loading