Added ProviderStateChanged event to ProviderManager (#112)

* Added ProviderStateChanged event to ProviderManager and adjust ProviderUpdated usage

* Removed unused ProviderUpdatedEventArgs and ProviderManagerChangedState

* Fixed provider pattern in ProviderStateTrigger
This commit is contained in:
Shane Weaver 2021-06-11 10:28:54 -07:00 коммит произвёл GitHub
Родитель 0a762c6213
Коммит e875ff5703
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
19 изменённых файлов: 83 добавлений и 160 удалений

Просмотреть файл

@ -7,12 +7,10 @@
This package includes .NET Standard authentication helpers such as:
- BaseProvider:
- IProvider:
- MockPRovider:
- MockProvider:
- ProviderManager:
- ProviderManagerChangedState:
- ProviderState:
- ProviderStateChangedEventArgs:
- ProviderUpdatedEventArgs:
</Description>
<PackageTags>Community Toolkit Provider Authentication Auth</PackageTags>
</PropertyGroup>

Просмотреть файл

@ -15,7 +15,7 @@ namespace CommunityToolkit.Authentication
/// ProviderManager.Instance.GlobalProvider = await MsalProvider.CreateAsync(...);
/// </code>
/// </example>
public partial class ProviderManager : INotifyPropertyChanged
public partial class ProviderManager
{
/// <summary>
/// Gets the name of the toolkit client to identify self in Graph calls.
@ -28,12 +28,14 @@ namespace CommunityToolkit.Authentication
public static ProviderManager Instance { get; } = new ProviderManager();
/// <summary>
/// Event called when the <see cref="IProvider"/> changes.
/// Event called when the <see cref="IProvider"/> instance changes.
/// </summary>
public event EventHandler<ProviderUpdatedEventArgs> ProviderUpdated;
public event EventHandler<IProvider> ProviderUpdated;
/// <inheritdoc/>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Event called when the <see cref="IProvider"/> state changes.
/// </summary>
public event EventHandler<ProviderStateChangedEventArgs> ProviderStateChanged;
private IProvider _provider;
@ -49,6 +51,7 @@ namespace CommunityToolkit.Authentication
set
{
var oldState = _provider?.State;
if (_provider != null)
{
_provider.StateChanged -= ProviderStateChanged;
@ -56,14 +59,14 @@ namespace CommunityToolkit.Authentication
_provider = value;
var newState = _provider?.State;
if (_provider != null)
{
_provider.StateChanged += ProviderStateChanged;
}
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(GlobalProvider)));
ProviderUpdated?.Invoke(this, new ProviderUpdatedEventArgs(ProviderManagerChangedState.ProviderChanged));
ProviderUpdated?.Invoke(this, new ProviderUpdatedEventArgs(ProviderManagerChangedState.ProviderStateChanged));
ProviderUpdated?.Invoke(this, _provider);
ProviderStateChanged?.Invoke(this, new ProviderStateChangedEventArgs(oldState, newState));
}
}
@ -71,10 +74,5 @@ namespace CommunityToolkit.Authentication
{
// Use Instance
}
private void ProviderStateChanged(object sender, ProviderStateChangedEventArgs e)
{
ProviderUpdated?.Invoke(this, new ProviderUpdatedEventArgs(ProviderManagerChangedState.ProviderStateChanged));
}
}
}

Просмотреть файл

@ -1,22 +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.
namespace CommunityToolkit.Authentication
{
/// <summary>
/// Enum representing reasons for provider state changing.
/// </summary>
public enum ProviderManagerChangedState
{
/// <summary>
/// The <see cref="IProvider"/> itself changed.
/// </summary>
ProviderChanged,
/// <summary>
/// The <see cref="IProvider.State"/> changed.
/// </summary>
ProviderStateChanged,
}
}

Просмотреть файл

@ -16,7 +16,7 @@ namespace CommunityToolkit.Authentication
/// </summary>
/// <param name="oldState">Previous <see cref="ProviderState"/>.</param>
/// <param name="newState">Current <see cref="ProviderState"/>.</param>
public ProviderStateChangedEventArgs(ProviderState oldState, ProviderState newState)
public ProviderStateChangedEventArgs(ProviderState? oldState, ProviderState? newState)
{
OldState = oldState;
NewState = newState;
@ -25,11 +25,11 @@ namespace CommunityToolkit.Authentication
/// <summary>
/// Gets the previous state of the <see cref="IProvider"/>.
/// </summary>
public ProviderState OldState { get; private set; }
public ProviderState? OldState { get; private set; }
/// <summary>
/// Gets the new state of the <see cref="IProvider"/>.
/// </summary>
public ProviderState NewState { get; private set; }
public ProviderState? NewState { get; private set; }
}
}

Просмотреть файл

@ -1,28 +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;
namespace CommunityToolkit.Authentication
{
/// <summary>
/// <see cref="EventArgs"/> class for <see cref="ProviderManager.ProviderUpdated"/> event.
/// </summary>
public class ProviderUpdatedEventArgs : EventArgs
{
/// <summary>
/// Initializes a new instance of the <see cref="ProviderUpdatedEventArgs"/> class.
/// </summary>
/// <param name="reason"><see cref="ProviderManagerChangedState"/> value for reason for update.</param>
public ProviderUpdatedEventArgs(ProviderManagerChangedState reason)
{
Reason = reason;
}
/// <summary>
/// Gets the reason for the provider update.
/// </summary>
public ProviderManagerChangedState Reason { get; private set; }
}
}

Просмотреть файл

@ -34,7 +34,7 @@ namespace CommunityToolkit.Graph.Uwp.Controls
{
this.DefaultStyleKey = typeof(LoginButton);
ProviderManager.Instance.ProviderUpdated += (sender, args) => LoadData();
ProviderManager.Instance.ProviderStateChanged += (sender, args) => LoadData();
}
/// <inheritdoc/>

Просмотреть файл

@ -91,7 +91,7 @@ namespace CommunityToolkit.Graph.Uwp.Controls
_defaultImage = new BitmapImage(new Uri(_defaultImageSource));
ProviderManager.Instance.ProviderUpdated += (sender, args) => LoadData();
ProviderManager.Instance.ProviderStateChanged += (sender, args) => LoadData();
}
/// <inheritdoc/>

Просмотреть файл

@ -47,16 +47,16 @@ namespace CommunityToolkit.Graph.Uwp
{
_dispatcherQueue = DispatcherQueue.GetForCurrentThread();
var weakEvent =
new WeakEventListener<ProviderStateTrigger, object, ProviderUpdatedEventArgs>(this)
new WeakEventListener<ProviderStateTrigger, object, ProviderStateChangedEventArgs>(this)
{
OnEventAction = (instance, source, args) => OnProviderUpdated(source, args),
OnDetachAction = (weakEventListener) => ProviderManager.Instance.ProviderUpdated -= weakEventListener.OnEvent,
OnEventAction = (instance, source, args) => OnProviderStateChanged(source, args),
OnDetachAction = (weakEventListener) => ProviderManager.Instance.ProviderStateChanged -= weakEventListener.OnEvent,
};
ProviderManager.Instance.ProviderUpdated += weakEvent.OnEvent;
ProviderManager.Instance.ProviderStateChanged += weakEvent.OnEvent;
UpdateState();
}
private void OnProviderUpdated(object sender, ProviderUpdatedEventArgs e)
private void OnProviderStateChanged(object sender, ProviderStateChangedEventArgs e)
{
_ = _dispatcherQueue.EnqueueAsync(UpdateState, DispatcherQueuePriority.Normal);
}

Просмотреть файл

@ -12,60 +12,30 @@ namespace CommunityToolkit.Graph.Extensions
/// </summary>
public static class ProviderExtensions
{
private static GraphServiceClient _client;
private static GraphServiceClient _betaClient;
static ProviderExtensions()
{
ProviderManager.Instance.ProviderUpdated += OnProviderUpdated;
}
private static void OnProviderUpdated(object sender, ProviderUpdatedEventArgs e)
{
var providerManager = sender as ProviderManager;
if (e.Reason == ProviderManagerChangedState.ProviderChanged || !(providerManager.GlobalProvider?.State == ProviderState.SignedIn))
{
_client = null;
_betaClient = null;
}
}
/// <summary>
/// Lazily gets a GraphServiceClient instance based on the current GlobalProvider.
/// The client instance is cleared whenever the GlobalProvider changes.
/// Gets a GraphServiceClient instance based on the current GlobalProvider.
/// </summary>
/// <param name="provider">The provider for authenticating Graph calls.</param>
/// <returns>A GraphServiceClient instance.</returns>
public static GraphServiceClient GetClient(this IProvider provider)
{
if (_client == null && provider?.State == ProviderState.SignedIn)
return new GraphServiceClient(new DelegateAuthenticationProvider(async (requestMessage) =>
{
_client = new GraphServiceClient(new DelegateAuthenticationProvider(async (requestMessage) =>
{
await provider.AuthenticateRequestAsync(requestMessage);
}));
}
return _client;
await provider.AuthenticateRequestAsync(requestMessage);
}));
}
/// <summary>
/// Lazily gets a GraphServiceClient instance based on the current GlobalProvider, but configured for the beta endpoint.
/// The beta client instance is cleared whenever the GlobalProvider changes.
/// Gets a GraphServiceClient instance based on the current GlobalProvider, but configured for the beta endpoint.
/// </summary>
/// <param name="provider">The provider for authenticating Graph calls.</param>
/// <returns>A GraphServiceClient instance configured for the beta endpoint.</returns>
public static GraphServiceClient GetBetaClient(this IProvider provider)
{
if (_betaClient == null && provider?.State == ProviderState.SignedIn)
return new GraphServiceClient("https://graph.microsoft.com/beta", new DelegateAuthenticationProvider(async (requestMessage) =>
{
_betaClient = new GraphServiceClient("https://graph.microsoft.com/beta", new DelegateAuthenticationProvider(async (requestMessage) =>
{
await provider.AuthenticateRequestAsync(requestMessage);
}));
}
return _betaClient;
await provider.AuthenticateRequestAsync(requestMessage);
}));
}
}
}

Просмотреть файл

@ -144,7 +144,7 @@ private async Task<IList<TodoTask>> GetDefaultTaskListAsync()
**That's all you need to get started!**
You can use the `ProviderManager.Instance` to listen to changes in authentication status with the `ProviderUpdated` event or get direct access to the [.NET Graph Beta API](https://github.com/microsoftgraph/msgraph-beta-sdk-dotnet) through `ProviderManager.Instance.GlobalProvider.GetBetaClient()`, just be sure to check if the `GlobalProvider` has been set first and its `State` is `SignedIn`:
You can use the `ProviderManager.Instance` to listen to changes in authentication status with the `ProviderStateChanged` event or get direct access to the [.NET Graph Beta API](https://github.com/microsoftgraph/msgraph-beta-sdk-dotnet) through `ProviderManager.Instance.GlobalProvider.GetBetaClient()`, just be sure to check if the `GlobalProvider` has been set first and its `State` is `SignedIn`:
```csharp
using CommunityToolkit.Authentication;

Просмотреть файл

@ -33,13 +33,12 @@ namespace SampleTest
this.InitializeComponent();
ProviderManager.Instance.ProviderUpdated += this.OnProviderUpdated;
ProviderManager.Instance.ProviderStateChanged += this.OnProviderStateChanged;
}
private void OnProviderUpdated(object sender, ProviderUpdatedEventArgs e)
private void OnProviderStateChanged(object sender, ProviderStateChangedEventArgs e)
{
if (e.Reason == ProviderManagerChangedState.ProviderStateChanged
&& sender is ProviderManager pm
&& pm.GlobalProvider.State == ProviderState.SignedIn)
if (e.NewState == ProviderState.SignedIn)
{
var graphClient = ProviderManager.Instance.GlobalProvider.GetClient();
@ -50,13 +49,26 @@ namespace SampleTest
}
else
{
CalendarViewBuilder = null;
MessagesBuilder = null;
PlannerTasksBuilder = null;
TeamsChannelMessagesBuilder = null;
ClearRequestBuilders();
}
}
private void OnProviderUpdated(object sender, IProvider provider)
{
if (provider == null)
{
ClearRequestBuilders();
}
}
private void ClearRequestBuilders()
{
CalendarViewBuilder = null;
MessagesBuilder = null;
PlannerTasksBuilder = null;
TeamsChannelMessagesBuilder = null;
}
public static string ToLocalTime(DateTimeTimeZone value)
{
// Workaround for https://github.com/microsoft/microsoft-ui-xaml/issues/2407

Просмотреть файл

@ -55,7 +55,7 @@ namespace SampleTest.Samples
_keyInputText = string.Empty;
_valueInputText = string.Empty;
ProviderManager.Instance.ProviderUpdated += (s, e) => CheckState();
ProviderManager.Instance.ProviderStateChanged += (s, e) => CheckState();
CheckState();
}

Просмотреть файл

@ -23,15 +23,13 @@ namespace ManualGraphRequestSample
{
InitializeComponent();
ProviderManager.Instance.ProviderUpdated += OnProviderUpdated;
ProviderManager.Instance.ProviderStateChanged += OnProviderStateChanged;
ProviderManager.Instance.GlobalProvider = new WindowsProvider(new string[] { "User.Read", "Tasks.ReadWrite" });
}
private async void OnProviderUpdated(object sender, ProviderUpdatedEventArgs e)
private async void OnProviderStateChanged(object sender, ProviderStateChangedEventArgs e)
{
IProvider provider = ProviderManager.Instance.GlobalProvider;
switch (provider?.State)
switch (e.NewState)
{
case ProviderState.Loading:
SignInButton.Content = "Loading...";

Просмотреть файл

@ -14,25 +14,24 @@ namespace UwpMsalProviderSample
{
this.InitializeComponent();
ProviderManager.Instance.ProviderUpdated += OnProviderUpdated;
ProviderManager.Instance.ProviderStateChanged += OnProviderStateChanged;
}
private async void OnProviderUpdated(object sender, ProviderUpdatedEventArgs e)
private async void OnProviderStateChanged(object sender, ProviderStateChangedEventArgs e)
{
var provider = ProviderManager.Instance.GlobalProvider;
if (provider == null || provider.State != ProviderState.SignedIn)
{
SignedInUserTextBlock.Text = "Please sign in.";
}
else
if (e.NewState == ProviderState.SignedIn)
{
SignedInUserTextBlock.Text = "Signed in as...";
var graphClient = provider.GetClient();
var graphClient = ProviderManager.Instance.GlobalProvider.GetClient();
var me = await graphClient.Me.Request().GetAsync();
SignedInUserTextBlock.Text = "Signed in as: " + me.DisplayName;
}
else
{
SignedInUserTextBlock.Text = "Please sign in.";
}
}
}
}

Просмотреть файл

@ -14,27 +14,26 @@ namespace UwpWindowsProviderSample
{
this.InitializeComponent();
ProviderManager.Instance.ProviderUpdated += OnProviderUpdated;
ProviderManager.Instance.ProviderStateChanged += OnProviderStateChanged;
}
private async void OnProviderUpdated(object sender, ProviderUpdatedEventArgs e)
private async void OnProviderStateChanged(object sender, ProviderStateChangedEventArgs e)
{
var provider = ProviderManager.Instance.GlobalProvider;
if (provider == null || provider.State != ProviderState.SignedIn)
{
SignedInUserTextBlock.Text = "Please sign in.";
ManagerButton.IsEnabled = false;
}
else
if (e.NewState == ProviderState.SignedIn)
{
ManagerButton.IsEnabled = true;
SignedInUserTextBlock.Text = "Signed in as...";
var graphClient = provider.GetClient();
var graphClient = ProviderManager.Instance.GlobalProvider.GetClient();
var me = await graphClient.Me.Request().GetAsync();
SignedInUserTextBlock.Text = "Signed in as: " + me.DisplayName;
}
else
{
SignedInUserTextBlock.Text = "Please sign in.";
ManagerButton.IsEnabled = false;
}
}
}
}

Просмотреть файл

@ -18,7 +18,7 @@ namespace WpfMsalProviderSample
{
InitializeComponent();
ProviderManager.Instance.ProviderUpdated += (s, e) => UpdateState();
ProviderManager.Instance.ProviderStateChanged += (s, e) => UpdateState();
UpdateState();
}

Просмотреть файл

@ -17,25 +17,24 @@ namespace WpfMsalProviderSample
{
InitializeComponent();
ProviderManager.Instance.ProviderUpdated += this.OnProviderUpdated;
ProviderManager.Instance.ProviderStateChanged += OnProviderStateChanged;
}
private async void OnProviderUpdated(object sender, ProviderUpdatedEventArgs e)
private async void OnProviderStateChanged(object sender, ProviderStateChangedEventArgs e)
{
var provider = ProviderManager.Instance.GlobalProvider;
if (provider == null || provider.State != ProviderState.SignedIn)
{
SignedInUserTextBlock.Text = "Please sign in.";
}
else
if (e.NewState == ProviderState.SignedIn)
{
SignedInUserTextBlock.Text = "Signed in as...";
var graphClient = provider.GetClient();
var graphClient = ProviderManager.Instance.GlobalProvider.GetClient();
var me = await graphClient.Me.Request().GetAsync();
SignedInUserTextBlock.Text = "Signed in as: " + me.DisplayName;
}
else
{
SignedInUserTextBlock.Text = "Please sign in.";
}
}
}
}

Просмотреть файл

@ -136,7 +136,7 @@ namespace UnitTests.UWP.Helpers
{
var provider = new WindowsProvider(new string[] { "User.Read", "Files.ReadWrite" }, autoSignIn: false);
ProviderManager.Instance.ProviderUpdated += (s, e) =>
ProviderManager.Instance.ProviderStateChanged += (s, e) =>
{
var providerManager = s as ProviderManager;
if (e.Reason == ProviderManagerChangedState.ProviderStateChanged && providerManager.GlobalProvider.State == ProviderState.SignedIn)

Просмотреть файл

@ -136,7 +136,7 @@ namespace UnitTests.UWP.Helpers
{
var provider = new WindowsProvider(new string[] { "User.ReadWrite" }, autoSignIn: false);
ProviderManager.Instance.ProviderUpdated += (s, e) =>
ProviderManager.Instance.ProviderStateChanged += (s, e) =>
{
var providerManager = s as ProviderManager;
if (e.Reason == ProviderManagerChangedState.ProviderStateChanged && providerManager.GlobalProvider.State == ProviderState.SignedIn)