Skip to content

Commit 8476f70

Browse files
committed
PR updates
1 parent 655caf6 commit 8476f70

File tree

7 files changed

+105
-145
lines changed

7 files changed

+105
-145
lines changed

Microsoft.Toolkit.Uwp/Helpers/ObjectStorage/ApplicationDataStorageHelper.CacheFolder.cs

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,10 @@ namespace Microsoft.Toolkit.Uwp.Helpers
1616
public partial class ApplicationDataStorageHelper
1717
{
1818
/// <summary>
19-
/// Gets the storage folder.
19+
/// Gets the local cache folder.
2020
/// </summary>
2121
public StorageFolder CacheFolder => AppData.LocalCacheFolder;
2222

23-
/// <summary>
24-
/// Determines if a directory item already exists in the LocalCacheFolder.
25-
/// </summary>
26-
/// <param name="itemName">Key of the file.</param>
27-
/// <returns>True if an item exists.</returns>
28-
public Task<bool> CacheItemExistsAsync(string itemName)
29-
{
30-
return ItemExistsAsync(CacheFolder, itemName);
31-
}
32-
3323
/// <summary>
3424
/// Retrieves an object from a file in the LocalCacheFolder.
3525
/// </summary>
@@ -47,7 +37,7 @@ public Task<T> ReadCacheFileAsync<T>(string filePath, T @default = default)
4737
/// </summary>
4838
/// <param name="folderPath">The path to the target folder.</param>
4939
/// <returns>A list of file types and names in the target folder.</returns>
50-
public Task<IList<Tuple<DirectoryItemType, string>>> ReadCacheFolderAsync(string folderPath)
40+
public Task<IEnumerable<(DirectoryItemType, string)>> ReadCacheFolderAsync(string folderPath)
5141
{
5242
return ReadFolderAsync(CacheFolder, folderPath);
5343
}

Microsoft.Toolkit.Uwp/Helpers/ObjectStorage/ApplicationDataStorageHelper.cs

Lines changed: 76 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace Microsoft.Toolkit.Uwp.Helpers
1515
/// <summary>
1616
/// Storage helper for files and folders living in Windows.Storage.ApplicationData storage endpoints.
1717
/// </summary>
18-
public partial class ApplicationDataStorageHelper : IFileStorageHelper, ISettingsStorageHelper
18+
public partial class ApplicationDataStorageHelper : IFileStorageHelper, ISettingsStorageHelper<string>
1919
{
2020
/// <summary>
2121
/// Get a new instance using ApplicationData.Current and the provided serializer.
@@ -53,9 +53,12 @@ public static async Task<ApplicationDataStorageHelper> GetForUserAsync(User user
5353
/// <summary>
5454
/// Gets the storage host.
5555
/// </summary>
56-
protected ApplicationData AppData { get; private set; }
56+
protected ApplicationData AppData { get; }
5757

58-
private readonly Toolkit.Helpers.IObjectSerializer _serializer;
58+
/// <summary>
59+
/// Gets the serializer for converting stored values.
60+
/// </summary>
61+
protected Toolkit.Helpers.IObjectSerializer Serializer { get; }
5962

6063
/// <summary>
6164
/// Initializes a new instance of the <see cref="ApplicationDataStorageHelper"/> class.
@@ -65,16 +68,54 @@ public static async Task<ApplicationDataStorageHelper> GetForUserAsync(User user
6568
public ApplicationDataStorageHelper(ApplicationData appData, Toolkit.Helpers.IObjectSerializer objectSerializer = null)
6669
{
6770
AppData = appData ?? throw new ArgumentNullException(nameof(appData));
68-
_serializer = objectSerializer ?? new Toolkit.Helpers.SystemSerializer();
71+
Serializer = objectSerializer ?? new Toolkit.Helpers.SystemSerializer();
6972
}
7073

71-
/// <inheritdoc />
74+
/// <summary>
75+
/// Determines whether a setting already exists.
76+
/// </summary>
77+
/// <param name="key">Key of the setting (that contains object).</param>
78+
/// <returns>True if a value exists.</returns>
7279
public bool KeyExists(string key)
7380
{
7481
return Settings.Values.ContainsKey(key);
7582
}
7683

7784
/// <inheritdoc />
85+
public T Read<T>(string key, T @default = default)
86+
{
87+
if (!Settings.Values.TryGetValue(key, out var valueObj) || valueObj == null)
88+
{
89+
return @default;
90+
}
91+
92+
return Serializer.Deserialize<T>(valueObj as string);
93+
}
94+
95+
/// <inheritdoc />
96+
public void Save<T>(string key, T value)
97+
{
98+
Settings.Values[key] = Serializer.Serialize(value);
99+
}
100+
101+
/// <inheritdoc />
102+
public void Delete(string key)
103+
{
104+
Settings.Values.Remove(key);
105+
}
106+
107+
/// <inheritdoc />
108+
public void Clear()
109+
{
110+
Settings.Values.Clear();
111+
}
112+
113+
/// <summary>
114+
/// Determines whether a setting already exists in composite.
115+
/// </summary>
116+
/// <param name="compositeKey">Key of the composite (that contains settings).</param>
117+
/// <param name="key">Key of the setting (that contains object).</param>
118+
/// <returns>True if a value exists.</returns>
78119
public bool KeyExists(string compositeKey, string key)
79120
{
80121
if (KeyExists(compositeKey))
@@ -89,18 +130,14 @@ public bool KeyExists(string compositeKey, string key)
89130
return false;
90131
}
91132

92-
/// <inheritdoc />
93-
public T Read<T>(string key, T @default = default)
94-
{
95-
if (!Settings.Values.TryGetValue(key, out var value) || value == null)
96-
{
97-
return @default;
98-
}
99-
100-
return _serializer.Deserialize<T>(value);
101-
}
102-
103-
/// <inheritdoc />
133+
/// <summary>
134+
/// Retrieves a single item by its key in composite.
135+
/// </summary>
136+
/// <typeparam name="T">Type of object retrieved.</typeparam>
137+
/// <param name="compositeKey">Key of the composite (that contains settings).</param>
138+
/// <param name="key">Key of the object.</param>
139+
/// <param name="default">Default value of the object.</param>
140+
/// <returns>The T object.</returns>
104141
public T Read<T>(string compositeKey, string key, T @default = default)
105142
{
106143
ApplicationDataCompositeValue composite = (ApplicationDataCompositeValue)Settings.Values[compositeKey];
@@ -109,20 +146,21 @@ public T Read<T>(string compositeKey, string key, T @default = default)
109146
string value = (string)composite[key];
110147
if (value != null)
111148
{
112-
return _serializer.Deserialize<T>(value);
149+
return Serializer.Deserialize<T>(value);
113150
}
114151
}
115152

116153
return @default;
117154
}
118155

119-
/// <inheritdoc />
120-
public void Save<T>(string key, T value)
121-
{
122-
Settings.Values[key] = _serializer.Serialize(value);
123-
}
124-
125-
/// <inheritdoc />
156+
/// <summary>
157+
/// Saves a group of items by its key in a composite.
158+
/// This method should be considered for objects that do not exceed 8k bytes during the lifetime of the application
159+
/// and for groups of settings which need to be treated in an atomic way.
160+
/// </summary>
161+
/// <typeparam name="T">Type of object saved.</typeparam>
162+
/// <param name="compositeKey">Key of the composite (that contains settings).</param>
163+
/// <param name="values">Objects to save.</param>
126164
public void Save<T>(string compositeKey, IDictionary<string, T> values)
127165
{
128166
if (KeyExists(compositeKey))
@@ -133,11 +171,11 @@ public void Save<T>(string compositeKey, IDictionary<string, T> values)
133171
{
134172
if (composite.ContainsKey(setting.Key))
135173
{
136-
composite[setting.Key] = _serializer.Serialize(setting.Value);
174+
composite[setting.Key] = Serializer.Serialize(setting.Value);
137175
}
138176
else
139177
{
140-
composite.Add(setting.Key, _serializer.Serialize(setting.Value));
178+
composite.Add(setting.Key, Serializer.Serialize(setting.Value));
141179
}
142180
}
143181
}
@@ -146,20 +184,18 @@ public void Save<T>(string compositeKey, IDictionary<string, T> values)
146184
ApplicationDataCompositeValue composite = new ApplicationDataCompositeValue();
147185
foreach (KeyValuePair<string, T> setting in values)
148186
{
149-
composite.Add(setting.Key, _serializer.Serialize(setting.Value));
187+
composite.Add(setting.Key, Serializer.Serialize(setting.Value));
150188
}
151189

152190
Settings.Values[compositeKey] = composite;
153191
}
154192
}
155193

156-
/// <inheritdoc />
157-
public void Delete(string key)
158-
{
159-
Settings.Values.Remove(key);
160-
}
161-
162-
/// <inheritdoc />
194+
/// <summary>
195+
/// Deletes a single item by its key in composite.
196+
/// </summary>
197+
/// <param name="compositeKey">Key of the composite (that contains settings).</param>
198+
/// <param name="key">Key of the object.</param>
163199
public void Delete(string compositeKey, string key)
164200
{
165201
if (KeyExists(compositeKey))
@@ -169,20 +205,14 @@ public void Delete(string compositeKey, string key)
169205
}
170206
}
171207

172-
/// <inheritdoc />
173-
public Task<bool> ItemExistsAsync(string itemName)
174-
{
175-
return ItemExistsAsync(Folder, itemName);
176-
}
177-
178208
/// <inheritdoc />
179209
public Task<T> ReadFileAsync<T>(string filePath, T @default = default)
180210
{
181211
return ReadFileAsync<T>(Folder, filePath, @default);
182212
}
183213

184214
/// <inheritdoc />
185-
public Task<IList<Tuple<DirectoryItemType, string>>> ReadFolderAsync(string folderPath)
215+
public Task<IEnumerable<(DirectoryItemType, string)>> ReadFolderAsync(string folderPath)
186216
{
187217
return ReadFolderAsync(Folder, folderPath);
188218
}
@@ -205,18 +235,6 @@ public Task DeleteItemAsync(string itemPath)
205235
return DeleteItemAsync(Folder, itemPath);
206236
}
207237

208-
/// <summary>
209-
/// Determine the existance of a file at the specified path.
210-
/// To check for folders, use <see cref="ItemExistsAsync(string)" />.
211-
/// </summary>
212-
/// <param name="fileName">The name of the file.</param>
213-
/// <param name="isRecursive">Whether the file should be searched for recursively.</param>
214-
/// <returns>A task with the result of the file query.</returns>
215-
public Task<bool> FileExistsAsync(string fileName, bool isRecursive = false)
216-
{
217-
return FileExistsAsync(Folder, fileName, isRecursive);
218-
}
219-
220238
/// <summary>
221239
/// Saves an object inside a file.
222240
/// </summary>
@@ -229,24 +247,13 @@ public Task<StorageFile> SaveFileAsync<T>(string filePath, T value)
229247
return SaveFileAsync<T>(Folder, filePath, value);
230248
}
231249

232-
private async Task<bool> ItemExistsAsync(StorageFolder folder, string itemName)
233-
{
234-
var item = await folder.TryGetItemAsync(itemName);
235-
return item != null;
236-
}
237-
238-
private Task<bool> FileExistsAsync(StorageFolder folder, string fileName, bool isRecursive)
239-
{
240-
return folder.FileExistsAsync(fileName, isRecursive);
241-
}
242-
243250
private async Task<T> ReadFileAsync<T>(StorageFolder folder, string filePath, T @default = default)
244251
{
245252
string value = await StorageFileHelper.ReadTextFromFileAsync(folder, filePath);
246-
return (value != null) ? _serializer.Deserialize<T>(value) : @default;
253+
return (value != null) ? Serializer.Deserialize<T>(value) : @default;
247254
}
248255

249-
private async Task<IList<Tuple<DirectoryItemType, string>>> ReadFolderAsync(StorageFolder folder, string folderPath)
256+
private async Task<IEnumerable<(DirectoryItemType, string)>> ReadFolderAsync(StorageFolder folder, string folderPath)
250257
{
251258
var targetFolder = await folder.GetFolderAsync(folderPath);
252259
var items = await targetFolder.GetItemsAsync();
@@ -257,13 +264,13 @@ private async Task<IList<Tuple<DirectoryItemType, string>>> ReadFolderAsync(Stor
257264
: item.IsOfType(StorageItemTypes.Folder) ? DirectoryItemType.Folder
258265
: DirectoryItemType.None;
259266

260-
return new Tuple<DirectoryItemType, string>(itemType, item.Name);
267+
return new ValueTuple<DirectoryItemType, string>(itemType, item.Name);
261268
}).ToList();
262269
}
263270

264271
private Task<StorageFile> SaveFileAsync<T>(StorageFolder folder, string filePath, T value)
265272
{
266-
return StorageFileHelper.WriteTextToFileAsync(folder, _serializer.Serialize(value)?.ToString(), filePath, CreationCollisionOption.ReplaceExisting);
273+
return StorageFileHelper.WriteTextToFileAsync(folder, Serializer.Serialize(value)?.ToString(), filePath, CreationCollisionOption.ReplaceExisting);
267274
}
268275

269276
private async Task CreateFolderAsync(StorageFolder folder, string folderPath)

Microsoft.Toolkit/Helpers/ObjectStorage/IFileStorageHelper.cs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,6 @@ namespace Microsoft.Toolkit.Helpers
1818
/// </summary>
1919
public interface IFileStorageHelper
2020
{
21-
/// <summary>
22-
/// Determines if a directory item already exists.
23-
/// </summary>
24-
/// <param name="itemName">Key of the file.</param>
25-
/// <returns>True if an item exists.</returns>
26-
Task<bool> ItemExistsAsync(string itemName);
27-
2821
/// <summary>
2922
/// Retrieves an object from a file.
3023
/// </summary>
@@ -38,8 +31,8 @@ public interface IFileStorageHelper
3831
/// Retrieves the listings for a folder and the item types.
3932
/// </summary>
4033
/// <param name="folderPath">The path to the target folder.</param>
41-
/// <returns>A list of file types and names in the target folder.</returns>
42-
Task<IList<Tuple<DirectoryItemType, string>>> ReadFolderAsync(string folderPath);
34+
/// <returns>A list of item types and names in the target folder.</returns>
35+
Task<IEnumerable<(DirectoryItemType ItemType, string Name)>> ReadFolderAsync(string folderPath);
4336

4437
/// <summary>
4538
/// Saves an object inside a file.

Microsoft.Toolkit/Helpers/ObjectStorage/IObjectSerializer.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5+
using System.Diagnostics.CodeAnalysis;
6+
57
namespace Microsoft.Toolkit.Helpers
68
{
79
/// <summary>
@@ -15,14 +17,16 @@ public interface IObjectSerializer
1517
/// <typeparam name="T">The type of the object to serialize.</typeparam>
1618
/// <param name="value">The object to serialize.</param>
1719
/// <returns>The serialized object.</returns>
18-
object? Serialize<T>(T value);
20+
[return: NotNullIfNotNull("value")]
21+
string? Serialize<T>(T value);
1922

2023
/// <summary>
21-
/// Deserialize a primitive or string into an object of the given type.
24+
/// Deserialize string into an object of the given type.
2225
/// </summary>
2326
/// <typeparam name="T">The type of the deserialized object.</typeparam>
2427
/// <param name="value">The string to deserialize.</param>
2528
/// <returns>The deserialized object.</returns>
26-
T Deserialize<T>(object value);
29+
[return: NotNullIfNotNull("value")]
30+
T Deserialize<T>(string value);
2731
}
2832
}

0 commit comments

Comments
 (0)