diff --git a/CommunityToolkit.Authentication.Msal/CommunityToolkit.Authentication.Msal.csproj b/CommunityToolkit.Authentication.Msal/CommunityToolkit.Authentication.Msal.csproj
index 3024215..c5157df 100644
--- a/CommunityToolkit.Authentication.Msal/CommunityToolkit.Authentication.Msal.csproj
+++ b/CommunityToolkit.Authentication.Msal/CommunityToolkit.Authentication.Msal.csproj
@@ -4,8 +4,10 @@
Windows Community Toolkit .NET Standard Auth Services
- This package includes .NET Standard authentication helpers such as:
- - MsalProvider:
+ This library provides an authentication provider based on the native Windows dialogues. It is part of the Windows Community Toolkit.
+
+ Classes:
+ - MsalProvider: An authentication provider based on MSAL for .NET.
Community Toolkit Provider Authentication Auth Msal
@@ -18,7 +20,4 @@
-
-
-
diff --git a/CommunityToolkit.Authentication.Uwp/CommunityToolkit.Authentication.Uwp.csproj b/CommunityToolkit.Authentication.Uwp/CommunityToolkit.Authentication.Uwp.csproj
index 01d1e55..5c68901 100644
--- a/CommunityToolkit.Authentication.Uwp/CommunityToolkit.Authentication.Uwp.csproj
+++ b/CommunityToolkit.Authentication.Uwp/CommunityToolkit.Authentication.Uwp.csproj
@@ -4,12 +4,12 @@
uap10.0.17134
Windows Community Toolkit Graph Uwp Authentication Provider
- This library provides an authentication provider based on the native Windows dialogues. It is part of the Windows Community Toolkit.
+ This library provides an authentication provider based on the native Windows dialogues.
Classes:
- - WindowsProvider:
+ - WindowsProvider: An authentication provider based on the native AccountsSettingsPane in Windows.
- UWP Toolkit Windows Microsoft Graph AadLogin Authentication Login
+ UWP Community Toolkit Provider Authentication Auth Windows
9.0
diff --git a/CommunityToolkit.Authentication/CommunityToolkit.Authentication.csproj b/CommunityToolkit.Authentication/CommunityToolkit.Authentication.csproj
index e9a1003..1c8f624 100644
--- a/CommunityToolkit.Authentication/CommunityToolkit.Authentication.csproj
+++ b/CommunityToolkit.Authentication/CommunityToolkit.Authentication.csproj
@@ -5,12 +5,11 @@
Windows Community Toolkit .NET Standard Auth Services
This package includes .NET Standard authentication helpers such as:
- - BaseProvider:
- - IProvider:
- - MockProvider:
- - ProviderManager:
- - ProviderState:
- - ProviderStateChangedEventArgs:
+
+ - BaseProvider: A base construct for building Graph Providers on top of.
+ - IProvider: Authentication provider interface to expose more states around the authentication process for Graph controls and helpers.
+ - ProviderManager: Shared provider manager used by controls and helpers to authenticate and call the Microsoft Graph.
+ - ProviderState: Represents the current authentication state of the session for a given IProvider.
Community Toolkit Provider Authentication Auth
diff --git a/CommunityToolkit.Graph.Uwp/CommunityToolkit.Graph.Uwp.csproj b/CommunityToolkit.Graph.Uwp/CommunityToolkit.Graph.Uwp.csproj
index 97f8bac..506adb7 100644
--- a/CommunityToolkit.Graph.Uwp/CommunityToolkit.Graph.Uwp.csproj
+++ b/CommunityToolkit.Graph.Uwp/CommunityToolkit.Graph.Uwp.csproj
@@ -6,13 +6,19 @@
This library provides Microsoft Graph UWP XAML controls. It is part of the Windows Community Toolkit.
- Classes:
- - GraphPresenter:
- - LoginButton: The Login Control leverages MSAL libraries to support the sign-in processes for Microsoft Graph and beyond.
+ Controls:
+ - GraphPresenter: A specialized ContentPresenter for fetching and displaying data from Microsoft Graph.
+ - LoginButton: The Login Control leverages the global authentication provider to support the sign-in processes for Microsoft Graph and beyond.
- PersonView: The PersonView control displays a user photo and can display their name and e-mail.
- - PeoplePicker: The PeoplePicker Control is a simple control that allows for selection of one or more users.
+ - PeoplePicker: The PeoplePicker Control is a simple control that allows for selection users.
+
+ Extensions:
+ - FrameworkElement.IsVisibleWhen(ProviderState): Extension on FrameworkElement for toggling visibility in response to changes in the global authentcation provider.
+
+ Triggers:
+ - ProviderStateTrigger: StateTrigger for reacting to changes in the global authentcation provider.
- UWP Toolkit Windows Controls MSAL Microsoft Graph AadLogin ProfileCard Person PeoplePicker Login
+ UWP Community Toolkit Windows Controls Microsoft Graph Login Person PeoplePicker Presenter
9.0
@@ -22,8 +28,8 @@
+
-
@@ -35,14 +41,6 @@
-
-
-
-
-
-
-
-
diff --git a/CommunityToolkit.Graph.Uwp/Controls/GraphPresenter/GraphPresenter.cs b/CommunityToolkit.Graph.Uwp/Controls/GraphPresenter/GraphPresenter.cs
index 97ffd48..ed8edb7 100644
--- a/CommunityToolkit.Graph.Uwp/Controls/GraphPresenter/GraphPresenter.cs
+++ b/CommunityToolkit.Graph.Uwp/Controls/GraphPresenter/GraphPresenter.cs
@@ -74,11 +74,11 @@ private async void GraphPresenter_Loaded(object sender, RoutedEventArgs e)
// Note: some interfaces from the Graph SDK don't implement IBaseRequestBuilder properly, see https://github.com/microsoftgraph/msgraph-sdk-dotnet/issues/722
if (RequestBuilder != null)
{
- var request = new BaseRequest(
- RequestBuilder.RequestUrl,
- RequestBuilder.Client); // TODO: Do we need separate Options here?
- request.Method = HttpMethods.GET;
- request.QueryOptions = QueryOptions?.Select(option => (Microsoft.Graph.QueryOption)option)?.ToList() ?? new List();
+ var request = new BaseRequest(RequestBuilder.RequestUrl, RequestBuilder.Client) // TODO: Do we need separate Options here?
+ {
+ Method = HttpMethods.GET,
+ QueryOptions = QueryOptions?.Select(option => (Microsoft.Graph.QueryOption)option)?.ToList() ?? new List(),
+ };
// Handle Special QueryOptions
if (!string.IsNullOrWhiteSpace(OrderBy))
diff --git a/CommunityToolkit.Graph.Uwp/Controls/PeoplePicker/PeoplePicker.cs b/CommunityToolkit.Graph.Uwp/Controls/PeoplePicker/PeoplePicker.cs
index 337605e..d3f1cb9 100644
--- a/CommunityToolkit.Graph.Uwp/Controls/PeoplePicker/PeoplePicker.cs
+++ b/CommunityToolkit.Graph.Uwp/Controls/PeoplePicker/PeoplePicker.cs
@@ -22,7 +22,7 @@ namespace CommunityToolkit.Graph.Uwp.Controls
///
public partial class PeoplePicker : TokenizingTextBox
{
- private DispatcherQueueTimer _typeTimer = null;
+ private readonly DispatcherQueueTimer _typeTimer = null;
///
/// Initializes a new instance of the class.
diff --git a/CommunityToolkit.Graph/CommunityToolkit.Graph.csproj b/CommunityToolkit.Graph/CommunityToolkit.Graph.csproj
index 3af7782..a45af4e 100644
--- a/CommunityToolkit.Graph/CommunityToolkit.Graph.csproj
+++ b/CommunityToolkit.Graph/CommunityToolkit.Graph.csproj
@@ -5,11 +5,17 @@
Windows Community Toolkit .NET Standard Graph Services
- This package includes .NET Standard code helpers such as:
- - GraphExtensions: Helpers for common tasks related to the Microsoft Graph used by the Microsoft.Toolkit.Graph.Controls.
- - ProviderExtensions: Extension on IProvider for accessing a pre-configured GraphServiceClient instance.
+ This package includes .NET Standard code helpers such as:
+
+ Extensions:
+ - GraphExtensions: Helpers for common tasks related to the Microsoft Graph in context of the available controls and helpers.
+ - ProviderExtensions: Extension on IProvider for accessing a pre-configured GraphServiceClient instance.
+
+ Helpers:
+ - OneDriveStorageHelper: A helper for interacting with data stored via files and folders in OneDrive.
+ - UserExtensionStorageHelper: A helper for interacting with open extensions on the Graph User to store data in key/value pairs.
- Windows Community Toolkit Graph Provider Extensions
+ Windows Community Toolkit Microsoft Graph Provider Extensions Helpers Roaming Settings
9.0
diff --git a/CommunityToolkit.Graph/Helpers/RoamingSettings/OneDriveDataSource.cs b/CommunityToolkit.Graph/Extensions/GraphExtensions.OneDrive.cs
similarity index 56%
rename from CommunityToolkit.Graph/Helpers/RoamingSettings/OneDriveDataSource.cs
rename to CommunityToolkit.Graph/Extensions/GraphExtensions.OneDrive.cs
index 4f4c686..ee5c93e 100644
--- a/CommunityToolkit.Graph/Helpers/RoamingSettings/OneDriveDataSource.cs
+++ b/CommunityToolkit.Graph/Extensions/GraphExtensions.OneDrive.cs
@@ -7,31 +7,27 @@
using System.IO;
using System.Text;
using System.Threading.Tasks;
-using CommunityToolkit.Authentication;
-using CommunityToolkit.Graph.Extensions;
using Microsoft.Graph;
using Microsoft.Toolkit.Helpers;
-namespace CommunityToolkit.Graph.Helpers.RoamingSettings
+namespace CommunityToolkit.Graph.Extensions
{
///
- /// Helpers for interacting with files in the special OneDrive AppRoot folder.
+ /// OneDrive focused extension methods to the Graph SDK used by the controls and helpers.
///
- internal static class OneDriveDataSource
+ public static partial class GraphExtensions
{
- private static GraphServiceClient Graph => ProviderManager.Instance.GlobalProvider?.GetClient();
-
///
/// Updates or create a new file on the remote with the provided content.
///
/// The type of object to save.
/// A representing the asynchronous operation.
- public static async Task SetFileAsync(string userId, string itemPath, T fileContents, IObjectSerializer serializer)
+ public static async Task SetFileAsync(this GraphServiceClient graph, string userId, string itemPath, T fileContents, IObjectSerializer serializer)
{
var json = serializer.Serialize(fileContents) as string;
using var stream = new MemoryStream(Encoding.UTF8.GetBytes(json));
- return await Graph.Users[userId].Drive.Special.AppRoot.ItemWithPath(itemPath).Content.Request().PutAsync(stream);
+ return await graph.Users[userId].Drive.Special.AppRoot.ItemWithPath(itemPath).Content.Request().PutAsync(stream);
}
///
@@ -39,9 +35,9 @@ public static async Task SetFileAsync(string userId, string itemPa
///
/// The type of object to return.
/// A representing the asynchronous operation.
- public static async Task GetFileAsync(string userId, string itemPath, IObjectSerializer serializer)
+ public static async Task GetFileAsync(this GraphServiceClient graph, string userId, string itemPath, IObjectSerializer serializer)
{
- Stream stream = await Graph.Users[userId].Drive.Special.AppRoot.ItemWithPath(itemPath).Content.Request().GetAsync();
+ Stream stream = await graph.Users[userId].Drive.Special.AppRoot.ItemWithPath(itemPath).Content.Request().GetAsync();
string streamContents = new StreamReader(stream).ReadToEnd();
@@ -52,12 +48,20 @@ public static async Task GetFileAsync(string userId, string itemPath, IObj
/// Delete the file from the remote.
///
/// A representing the asynchronous operation.
- public static async Task DeleteItemAsync(string userId, string itemPath)
+ public static async Task DeleteItemAsync(this GraphServiceClient graph, string userId, string itemPath)
{
- await Graph.Users[userId].Drive.Special.AppRoot.ItemWithPath(itemPath).Request().DeleteAsync();
+ await graph.Users[userId].Drive.Special.AppRoot.ItemWithPath(itemPath).Request().DeleteAsync();
}
- public static async Task CreateFolderAsync(string userId, string folderName, string path = null)
+ ///
+ /// Ensure a folder exists by name.
+ ///
+ /// Instance of the .
+ /// The id of the target Graph user.
+ /// The name of the new folder.
+ /// The path to create the new folder in.
+ /// A representing the asynchronous operation.
+ public static async Task CreateFolderAsync(this GraphServiceClient graph, string userId, string folderName, string path = null)
{
var folderDriveItem = new DriveItem()
{
@@ -67,17 +71,24 @@ public static async Task CreateFolderAsync(string userId, string folderName, str
if (path != null)
{
- await Graph.Users[userId].Drive.Special.AppRoot.ItemWithPath(path).Children.Request().AddAsync(folderDriveItem);
+ await graph.Users[userId].Drive.Special.AppRoot.ItemWithPath(path).Children.Request().AddAsync(folderDriveItem);
}
else
{
- await Graph.Users[userId].Drive.Special.AppRoot.Children.Request().AddAsync(folderDriveItem);
+ await graph.Users[userId].Drive.Special.AppRoot.Children.Request().AddAsync(folderDriveItem);
}
}
- public static async Task> ReadFolderAsync(string userId, string folderPath)
+ ///
+ /// Retrieve a list of directory items with names and types.
+ ///
+ /// Instance of the .
+ /// The id of the target Graph user.
+ /// The path to create the new folder in.
+ /// A with the directory listings.
+ public static async Task> ReadFolderAsync(this GraphServiceClient graph, string userId, string folderPath)
{
- IDriveItemChildrenCollectionPage folderContents = await Graph.Users[userId].Drive.Special.AppRoot.ItemWithPath(folderPath).Children.Request().GetAsync();
+ IDriveItemChildrenCollectionPage folderContents = await graph.Users[userId].Drive.Special.AppRoot.ItemWithPath(folderPath).Children.Request().GetAsync();
var results = new List<(DirectoryItemType, string)>();
foreach (var item in folderContents)
diff --git a/CommunityToolkit.Graph/Helpers/RoamingSettings/UserExtensionDataSource.cs b/CommunityToolkit.Graph/Extensions/GraphExtensions.UserExtensions.cs
similarity index 65%
rename from CommunityToolkit.Graph/Helpers/RoamingSettings/UserExtensionDataSource.cs
rename to CommunityToolkit.Graph/Extensions/GraphExtensions.UserExtensions.cs
index 2a035b6..a0a5d06 100644
--- a/CommunityToolkit.Graph/Helpers/RoamingSettings/UserExtensionDataSource.cs
+++ b/CommunityToolkit.Graph/Extensions/GraphExtensions.UserExtensions.cs
@@ -4,28 +4,28 @@
using System;
using System.Collections.Generic;
+using System.IO;
using System.Net.Http;
+using System.Text;
using System.Threading.Tasks;
-using CommunityToolkit.Authentication;
-using CommunityToolkit.Graph.Extensions;
using Microsoft.Graph;
+using Microsoft.Toolkit.Helpers;
-namespace CommunityToolkit.Graph.Helpers.RoamingSettings
+namespace CommunityToolkit.Graph.Extensions
{
///
- /// Manages Graph interaction with open extensions on the user.
+ /// UserExtensions focused extension methods to the Graph SDK used by the controls and helpers.
///
- internal static class UserExtensionDataSource
+ public static partial class GraphExtensions
{
- private static GraphServiceClient Graph => ProviderManager.Instance.GlobalProvider?.GetClient();
-
///
/// Retrieve an extension object for a user.
///
+ /// Instance of the .
/// The user to access.
/// The extension to retrieve.
/// The extension result.
- public static async Task GetExtension(string userId, string extensionId)
+ public static async Task GetExtension(this GraphServiceClient graph, string userId, string extensionId)
{
if (string.IsNullOrWhiteSpace(extensionId))
{
@@ -37,33 +37,35 @@ public static async Task GetExtension(string userId, string extension
throw new ArgumentNullException(nameof(userId));
}
- var extension = await Graph.Users[userId].Extensions[extensionId].Request().GetAsync();
+ var extension = await graph.Users[userId].Extensions[extensionId].Request().GetAsync();
return extension;
}
///
/// Get all extension objects for a user.
///
+ /// Instance of the .
/// The user to access.
/// All extension results.
- public static async Task> GetAllExtensions(string userId)
+ public static async Task> GetAllExtensions(this GraphServiceClient graph, string userId)
{
if (string.IsNullOrWhiteSpace(userId))
{
throw new ArgumentNullException(nameof(userId));
}
- var extensions = await Graph.Users[userId].Extensions.Request().GetAsync();
+ var extensions = await graph.Users[userId].Extensions.Request().GetAsync();
return extensions;
}
///
/// Create a new extension object on a user.
///
+ /// Instance of the .
/// The user to access.
/// The id of the new extension.
/// The newly created extension.
- public static async Task CreateExtension(string userId, string extensionId)
+ public static async Task CreateExtension(this GraphServiceClient graph, string userId, string extensionId)
{
if (string.IsNullOrWhiteSpace(extensionId))
{
@@ -78,13 +80,13 @@ public static async Task CreateExtension(string userId, string extens
try
{
// Try to see if the extension already exists.
- return await GetExtension(userId, extensionId);
+ return await graph.GetExtension(userId, extensionId);
}
catch
{
}
- string requestUrl = Graph.Users[userId].Extensions.Request().RequestUrl;
+ string requestUrl = graph.Users[userId].Extensions.Request().RequestUrl;
string json = "{" +
"\"@odata.type\": \"microsoft.graph.openTypeExtension\"," +
@@ -93,13 +95,13 @@ public static async Task CreateExtension(string userId, string extens
HttpRequestMessage hrm = new (HttpMethod.Post, requestUrl);
hrm.Content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
- await Graph.AuthenticationProvider.AuthenticateRequestAsync(hrm);
- HttpResponseMessage response = await Graph.HttpProvider.SendAsync(hrm);
+ await graph.AuthenticationProvider.AuthenticateRequestAsync(hrm);
+ HttpResponseMessage response = await graph.HttpProvider.SendAsync(hrm);
if (response.IsSuccessStatusCode)
{
// Deserialize into Extension object.
var content = await response.Content.ReadAsStringAsync();
- var extension = Graph.HttpProvider.Serializer.DeserializeObject(content);
+ var extension = graph.HttpProvider.Serializer.DeserializeObject(content);
return extension;
}
@@ -109,10 +111,11 @@ public static async Task CreateExtension(string userId, string extens
///
/// Delete a user extension by id.
///
+ /// Instance of the .
/// The user to access.
/// The id of the extension to delete.
/// A task.
- public static async Task DeleteExtension(string userId, string extensionId)
+ public static async Task DeleteExtension(this GraphServiceClient graph, string userId, string extensionId)
{
if (string.IsNullOrWhiteSpace(extensionId))
{
@@ -126,7 +129,7 @@ public static async Task DeleteExtension(string userId, string extensionId)
try
{
- await GetExtension(userId, extensionId);
+ await graph.GetExtension(userId, extensionId);
}
catch
{
@@ -134,51 +137,19 @@ public static async Task DeleteExtension(string userId, string extensionId)
return;
}
- await Graph.Users[userId].Extensions[extensionId].Request().DeleteAsync();
- }
-
- ///
- /// Get a value from an extension by key.
- ///
- /// The type of object to return.
- /// The target extension.
- /// The key for the desired value.
- /// The value for the provided key.
- public static T GetValue(this Extension extension, string key)
- {
- return (T)GetValue(extension, key);
- }
-
- ///
- /// Get a value from a user extension by key.
- ///
- /// The target extension.
- /// The key for the desired value.
- /// The value for the provided key.
- public static object GetValue(this Extension extension, string key)
- {
- if (string.IsNullOrWhiteSpace(key))
- {
- throw new ArgumentNullException(nameof(key));
- }
-
- if (extension.AdditionalData.ContainsKey(key))
- {
- return extension.AdditionalData[key];
- }
-
- return null;
+ await graph.Users[userId].Extensions[extensionId].Request().DeleteAsync();
}
///
/// Sets a user extension value at the specified key.
///
+ /// Instance of the .
/// The user to access.
/// The id of the target extension.
/// The key.
/// The value to set.
/// A task.
- public static async Task SetValue(string userId, string extensionId, string key, object value)
+ public static async Task SetValue(this GraphServiceClient graph, string userId, string extensionId, string key, object value)
{
if (string.IsNullOrWhiteSpace(userId))
{
@@ -198,7 +169,7 @@ public static async Task SetValue(string userId, string extensionId, string key,
var extensionToUpdate = (Extension)Activator.CreateInstance(typeof(Extension), true);
extensionToUpdate.AdditionalData = new Dictionary() { { key, value } };
- await Graph.Users[userId].Extensions[extensionId].Request().UpdateAsync(extensionToUpdate);
+ await graph.Users[userId].Extensions[extensionId].Request().UpdateAsync(extensionToUpdate);
}
}
-}
\ No newline at end of file
+}
diff --git a/CommunityToolkit.Graph/Extensions/GraphExtensions.Users.cs b/CommunityToolkit.Graph/Extensions/GraphExtensions.Users.cs
index 6a641ca..98d82af 100644
--- a/CommunityToolkit.Graph/Extensions/GraphExtensions.Users.cs
+++ b/CommunityToolkit.Graph/Extensions/GraphExtensions.Users.cs
@@ -20,7 +20,11 @@ public static partial class GraphExtensions
/// A representing the asynchronous operation.
public static async Task GetMeAsync(this GraphServiceClient graph)
{
- return await graph.Me.Request().GetAsync();
+ return await graph
+ .Me
+ .Request()
+ .WithScopes(new string[] { "user.read" })
+ .GetAsync();
}
///
@@ -31,7 +35,11 @@ public static async Task GetMeAsync(this GraphServiceClient graph)
/// A representing the asynchronous operation.
public static async Task GetUserAsync(this GraphServiceClient graph, string userId)
{
- return await graph.Users[userId].Request().GetAsync();
+ return await graph
+ .Users[userId]
+ .Request()
+ .WithScopes(new string[] { "user.read" })
+ .GetAsync();
}
///
@@ -46,7 +54,7 @@ public static async Task FindUserAsync(this Gr
.Users
.Request()
.Filter($"startswith(displayName, '{query}') or startswith(givenName, '{query}') or startswith(surname, '{query}') or startswith(mail, '{query}') or startswith(userPrincipalName, '{query}')")
- ////.WithScopes(new string[] { "user.readbasic.all" })
+ .WithScopes(new string[] { "user.readbasic.all" })
.GetAsync();
}
@@ -63,7 +71,7 @@ public static async Task GetUserPhoto(this GraphServiceClient graph, str
.Photo
.Content
.Request()
- ////.WithScopes(new string[] { "user.readbasic.all" })
+ .WithScopes(new string[] { "user.readbasic.all" })
.GetAsync();
}
@@ -79,7 +87,7 @@ public static async Task GetMyPhotoAsync(this GraphServiceClient graph)
.Photo
.Content
.Request()
- ////.WithScopes(new string[] { "user.read" })
+ .WithScopes(new string[] { "user.read" })
.GetAsync();
}
}
diff --git a/CommunityToolkit.Graph/Helpers/RoamingSettings/IRemoteSettingsStorageHelper.cs b/CommunityToolkit.Graph/Helpers/RoamingSettings/IRemoteSettingsStorageHelper.cs
deleted file mode 100644
index 66601d0..0000000
--- a/CommunityToolkit.Graph/Helpers/RoamingSettings/IRemoteSettingsStorageHelper.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-// 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.Text;
-using System.Threading.Tasks;
-using Microsoft.Toolkit.Helpers;
-
-namespace CommunityToolkit.Graph.Helpers.RoamingSettings
-{
- ///
- /// Describes a remote settings storage location with basic sync support.
- ///
- /// The type of keys to use for accessing values.
- public interface IRemoteSettingsStorageHelper : ISettingsStorageHelper
- {
- ///
- /// Gets or sets an event that fires whenever a sync request has completed.
- ///
- EventHandler SyncCompleted { get; set; }
-
- ///
- /// Gets or sets a value an event that fires whenever a remote sync request has failed.
- ///
- EventHandler SyncFailed { get; set; }
-
- ///
- /// Update the remote extension to match the local cache and retrieve any new keys. Any existing remote values are replaced.
- ///
- /// The freshly synced user extension.
- Task Sync();
- }
-}
diff --git a/CommunityToolkit.Graph/Helpers/RoamingSettings/OneDriveStorageHelper.cs b/CommunityToolkit.Graph/Helpers/RoamingSettings/OneDriveStorageHelper.cs
index 90e4259..c9b56fd 100644
--- a/CommunityToolkit.Graph/Helpers/RoamingSettings/OneDriveStorageHelper.cs
+++ b/CommunityToolkit.Graph/Helpers/RoamingSettings/OneDriveStorageHelper.cs
@@ -9,12 +9,13 @@
using System.Threading.Tasks;
using CommunityToolkit.Authentication;
using CommunityToolkit.Graph.Extensions;
+using Microsoft.Graph;
using Microsoft.Toolkit.Helpers;
namespace CommunityToolkit.Graph.Helpers.RoamingSettings
{
///
- /// A base class for easily building roaming settings helper implementations.
+ /// An IFileStorageHelper implementation for interacting with data stored via files and folders in OneDrive.
///
public class OneDriveStorageHelper : IFileStorageHelper
{
@@ -35,13 +36,8 @@ public class OneDriveStorageHelper : IFileStorageHelper
/// A new instance of the configured for the current Graph user.
public static async Task CreateForCurrentUserAsync(IObjectSerializer objectSerializer = null)
{
- var provider = ProviderManager.Instance.GlobalProvider;
- if (provider == null || provider.State != ProviderState.SignedIn)
- {
- throw new InvalidOperationException($"The {nameof(ProviderManager.GlobalProvider)} must be set and signed in to create a new {nameof(OneDriveStorageHelper)} for the current user.");
- }
-
- var me = await provider.GetClient().Me.Request().GetAsync();
+ var graph = GetGraphClient();
+ var me = await graph.GetMeAsync();
var userId = me.Id;
return new OneDriveStorageHelper(userId, objectSerializer);
@@ -61,25 +57,29 @@ public OneDriveStorageHelper(string userId, IObjectSerializer objectSerializer =
///
public async Task ReadFileAsync(string filePath, T @default = default)
{
- return await OneDriveDataSource.GetFileAsync(UserId, filePath, Serializer) ?? @default;
+ var graph = ProviderManager.Instance.GlobalProvider.GetClient();
+ return await graph.GetFileAsync(UserId, filePath, Serializer) ?? @default;
}
///
public Task> ReadFolderAsync(string folderPath)
{
- return OneDriveDataSource.ReadFolderAsync(UserId, folderPath);
+ var graph = GetGraphClient();
+ return graph.ReadFolderAsync(UserId, folderPath);
}
///
public async Task CreateFileAsync(string filePath, T value)
{
- await OneDriveDataSource.SetFileAsync(UserId, filePath, value, Serializer);
+ var graph = GetGraphClient();
+ await graph.SetFileAsync(UserId, filePath, value, Serializer);
}
///
public Task CreateFolderAsync(string folderName)
{
- return OneDriveDataSource.CreateFolderAsync(UserId, folderName);
+ var graph = GetGraphClient();
+ return graph.CreateFolderAsync(UserId, folderName);
}
///
@@ -90,13 +90,26 @@ public Task CreateFolderAsync(string folderName)
/// A task.
public Task CreateFolderAsync(string folderName, string folderPath)
{
- return OneDriveDataSource.CreateFolderAsync(UserId, folderName, folderPath);
+ var graph = GetGraphClient();
+ return graph.CreateFolderAsync(UserId, folderName, folderPath);
}
///
public Task DeleteItemAsync(string itemPath)
{
- return OneDriveDataSource.DeleteItemAsync(UserId, itemPath);
+ var graph = GetGraphClient();
+ return graph.DeleteItemAsync(UserId, itemPath);
+ }
+
+ private static GraphServiceClient GetGraphClient()
+ {
+ var provider = ProviderManager.Instance.GlobalProvider;
+ if (provider == null || provider.State != ProviderState.SignedIn)
+ {
+ throw new InvalidOperationException($"The {nameof(ProviderManager.GlobalProvider)} must be set and signed in to perform this action.");
+ }
+
+ return provider.GetClient();
}
}
}
diff --git a/CommunityToolkit.Graph/Helpers/RoamingSettings/UserExtensionStorageHelper.cs b/CommunityToolkit.Graph/Helpers/RoamingSettings/UserExtensionStorageHelper.cs
index ee150ae..8c22835 100644
--- a/CommunityToolkit.Graph/Helpers/RoamingSettings/UserExtensionStorageHelper.cs
+++ b/CommunityToolkit.Graph/Helpers/RoamingSettings/UserExtensionStorageHelper.cs
@@ -17,9 +17,9 @@
namespace CommunityToolkit.Graph.Helpers.RoamingSettings
{
///
- /// An IObjectStorageHelper implementation using open extensions on the Graph User for storing key/value pairs.
+ /// An ISettingsStorageHelper implementation using open extensions on the Graph User for storing key/value pairs.
///
- public class UserExtensionStorageHelper : IRemoteSettingsStorageHelper
+ public class UserExtensionStorageHelper : ISettingsStorageHelper
{
private static readonly IList ReservedKeys = new List { "responseHeaders", "statusCode", "@odata.context" };
private static readonly SemaphoreSlim SyncLock = new (1);
@@ -30,7 +30,7 @@ public class UserExtensionStorageHelper : IRemoteSettingsStorageHelper
public EventHandler SyncCompleted { get; set; }
///
- /// gets or sets an event that fires whenever a remote sync request has failed.
+ /// Gets or sets an event that fires whenever a remote sync request has failed.
///
public EventHandler SyncFailed { get; set; }
@@ -82,6 +82,21 @@ public static async Task CreateForCurrentUserAsync(s
return new UserExtensionStorageHelper(extensionId, userId, objectSerializer);
}
+ ///
+ /// Retrieve an instance of the GraphServiceClient, or throws an exception if not signed in.
+ ///
+ /// A instance.
+ protected static GraphServiceClient GetGraphClient()
+ {
+ var provider = ProviderManager.Instance.GlobalProvider;
+ if (provider == null || provider.State != ProviderState.SignedIn)
+ {
+ throw new InvalidOperationException($"The {nameof(ProviderManager.GlobalProvider)} must be set and signed in to perform this action.");
+ }
+
+ return provider.GetClient();
+ }
+
///
/// An indexer for easily accessing key values.
///
@@ -156,14 +171,16 @@ public virtual async Task Sync()
try
{
+ var graph = GetGraphClient();
+
IDictionary remoteData = null;
// Check if the extension should be cleared.
if (_cleared)
{
// Delete and re-create the remote extension.
- await UserExtensionDataSource.DeleteExtension(UserId, ExtensionId);
- Extension extension = await UserExtensionDataSource.CreateExtension(UserId, ExtensionId);
+ await graph.DeleteExtension(UserId, ExtensionId);
+ Extension extension = await graph.CreateExtension(UserId, ExtensionId);
remoteData = extension.AdditionalData;
_cleared = false;
@@ -171,7 +188,7 @@ public virtual async Task Sync()
else
{
// Get the remote extension.
- Extension extension = await UserExtensionDataSource.GetExtension(UserId, ExtensionId);
+ Extension extension = await graph.GetExtension(UserId, ExtensionId);
remoteData = extension.AdditionalData;
}
@@ -208,9 +225,10 @@ public virtual async Task Sync()
SyncCompleted?.Invoke(this, new EventArgs());
}
- catch
+ catch (Exception e)
{
SyncFailed?.Invoke(this, new EventArgs());
+ throw e;
}
finally
{