From ebd70d920b3ed804c6647368355f7005e6f70664 Mon Sep 17 00:00:00 2001 From: Josh Buedel Date: Mon, 19 Feb 2024 21:01:07 -0600 Subject: [PATCH] Autosave Add capability to automatically save changes to RoleStore like already exists on UserStore. Drive both of these via a new member on options class. --- RavenDB.Identity/RavenDbIdentityOptions.cs | 11 ++++++- RavenDB.Identity/RoleStore.cs | 35 +++++++++++----------- RavenDB.Identity/UserStore.cs | 16 ++++++++++ 3 files changed, 44 insertions(+), 18 deletions(-) diff --git a/RavenDB.Identity/RavenDbIdentityOptions.cs b/RavenDB.Identity/RavenDbIdentityOptions.cs index 503285f..aae854a 100644 --- a/RavenDB.Identity/RavenDbIdentityOptions.cs +++ b/RavenDB.Identity/RavenDbIdentityOptions.cs @@ -1,3 +1,5 @@ +using Raven.Client.Documents.Session; + namespace Raven.Identity { /// @@ -12,6 +14,13 @@ public class RavenDbIdentityOptions /// Indexes need to be deployed to server in order for static index queries to work. /// /// - public bool UseStaticIndexes { get; set; } + public bool UseStaticIndexes { get; set; } + + /// + /// If set, changes detected in and + /// will be saved to Raven immediately (by calling ). + /// Leave false (the default) if you've implemented the save changes call in middleware. + /// + public bool AutoSaveChanges { get; set; } } } \ No newline at end of file diff --git a/RavenDB.Identity/RoleStore.cs b/RavenDB.Identity/RoleStore.cs index 26c6e6c..09c00b6 100644 --- a/RavenDB.Identity/RoleStore.cs +++ b/RavenDB.Identity/RoleStore.cs @@ -1,4 +1,5 @@ using Microsoft.AspNetCore.Identity; +using Microsoft.Extensions.Options; using Raven.Client; using System; using System.Collections.Generic; @@ -51,9 +52,11 @@ public class RoleStore : RoleStore /// Constructs a new instance of . /// /// The . + /// /// The . - public RoleStore(IAsyncDocumentSession context, IdentityErrorDescriber? describer = null) - : base(context, describer) + public RoleStore(IAsyncDocumentSession context, IOptions options, + IdentityErrorDescriber? describer = null) + : base(context, options, describer) { } @@ -80,14 +83,17 @@ public abstract class RoleStore : where TRole : IdentityRole where TRoleClaim : IdentityRoleClaim { + private readonly IOptions options; /// /// Constructs a new instance of . /// /// The . /// The . - public RoleStore(IAsyncDocumentSession context, IdentityErrorDescriber? describer = null) + public RoleStore(IAsyncDocumentSession context, IOptions options, + IdentityErrorDescriber? describer = null) { AsyncSession = context ?? throw new ArgumentNullException(nameof(context)); + this.options = options ?? throw new ArgumentNullException(nameof(options)); ErrorDescriber = describer ?? new IdentityErrorDescriber(); } @@ -104,23 +110,18 @@ public RoleStore(IAsyncDocumentSession context, IdentityErrorDescriber? describe /// public IdentityErrorDescriber ErrorDescriber { get; set; } - /// - /// Gets or sets a flag indicating if changes should be persisted after CreateAsync, UpdateAsync and DeleteAsync are called. - /// - /// - /// True if changes should be automatically persisted, otherwise false. - /// - public bool AutoSaveChanges { get; set; } = true; - /// Saves the current store. - /// The used to propagate notifications that the operation should be canceled. - /// The that represents the asynchronous operation. + /// + /// The used to propagate notifications that the operation + /// should be canceled. + /// + /// The that represents the asynchronous operation. private async Task SaveChanges(CancellationToken cancellationToken) { - if (AutoSaveChanges) - { - await AsyncSession.SaveChangesAsync(cancellationToken); - } + if (options.Value.AutoSaveChanges) + { + await AsyncSession.SaveChangesAsync(cancellationToken); + } } #region IQueryableRoleStore diff --git a/RavenDB.Identity/UserStore.cs b/RavenDB.Identity/UserStore.cs index 816f8c7..28c7a8f 100644 --- a/RavenDB.Identity/UserStore.cs +++ b/RavenDB.Identity/UserStore.cs @@ -81,6 +81,17 @@ public virtual void Dispose() #endregion + #region AutoSaveChanges implementation + + private async Task SaveChangesAsync() + { + if (options.Value.AutoSaveChanges) + { + await DbSession.SaveChangesAsync(); + } + } + + #endregion #region IUserStore implementation /// @@ -208,6 +219,7 @@ public virtual async Task UpdateAsync(TUser user, CancellationTo logger.LogTrace("User {UserId} did not have modified Email, saving normally", user.Id); // Email didn't change, so no reservation to update. Just save the user data + await SaveChangesAsync(); return IdentityResult.Success; } @@ -226,6 +238,8 @@ public virtual async Task UpdateAsync(TUser user, CancellationTo // See if the email change was only due to case sensitivity. if (string.Equals(user.Email, oldEmail, StringComparison.InvariantCultureIgnoreCase)) { + // Save the other user data. + await SaveChangesAsync(); return IdentityResult.Success; } @@ -238,6 +252,8 @@ public virtual async Task UpdateAsync(TUser user, CancellationTo } await TryRemoveMigratedEmailReservation(oldEmail, user.Email); + + await SaveChangesAsync(); return IdentityResult.Success; }