Clear member cache by older user name when member user name is updated (16) (#19690)

* Pass notification state to cache refreshers.
Pass previous user name into member saved notification state and use when refreshing cache to clear the member by keys based on this.

* Fixed issue raised in code review.

* Fixed casing for state key.

* Added removed parameter to unit tests.

* Fix breaking change.
This commit is contained in:
Andy Butland
2025-07-08 11:28:11 +02:00
committed by GitHub
parent e00dcef4d6
commit 118b26a8b9
33 changed files with 312 additions and 10 deletions

View File

@@ -10,11 +10,20 @@ public abstract class DistributedCacheNotificationHandlerBase<TEntity, TNotifica
{
/// <inheritdoc />
public void Handle(TNotification notification)
=> Handle(GetEntities(notification));
=> Handle(
GetEntities(notification),
notification is StatefulNotification statefulNotification
? statefulNotification.State
: new Dictionary<string, object?>());
/// <inheritdoc />
public void Handle(IEnumerable<TNotification> notifications)
=> Handle(notifications.SelectMany(GetEntities));
{
foreach (TNotification notification in notifications)
{
Handle(notification);
}
}
/// <summary>
/// Gets the entities from the specified notification.
@@ -25,9 +34,23 @@ public abstract class DistributedCacheNotificationHandlerBase<TEntity, TNotifica
/// </returns>
protected abstract IEnumerable<TEntity> GetEntities(TNotification notification);
// TODO (V18): When removing the obsolete method, make the remaining Handle method abstract
// rather than virtual. It couldn't be made abstract when introduced as that would be a breaking change.
/// <summary>
/// Handles the specified entities.
/// </summary>
/// <param name="entities">The entities.</param>
[Obsolete("Please use the overload taking all parameters. Scheduled for removal in Umbraco 18.")]
protected abstract void Handle(IEnumerable<TEntity> entities);
/// <summary>
/// Handles the specified entities.
/// </summary>
/// <param name="entities">The entities.</param>
/// <param name="state">The notification state.</param>
protected virtual void Handle(IEnumerable<TEntity> entities, IDictionary<string, object?> state)
#pragma warning disable CS0618 // Type or member is obsolete
=> Handle(entities);
#pragma warning restore CS0618 // Type or member is obsolete
}

View File

@@ -18,6 +18,11 @@ public sealed class ContentTreeChangeDistributedCacheNotificationHandler : TreeC
=> _distributedCache = distributedCache;
/// <inheritdoc />
[Obsolete("Scheduled for removal in Umbraco 18.")]
protected override void Handle(IEnumerable<TreeChange<IContent>> entities)
=> Handle(entities, new Dictionary<string, object?>());
/// <inheritdoc />
protected override void Handle(IEnumerable<TreeChange<IContent>> entities, IDictionary<string, object?> state)
=> _distributedCache.RefreshContentCache(entities);
}

View File

@@ -18,6 +18,11 @@ public sealed class ContentTypeChangedDistributedCacheNotificationHandler : Cont
=> _distributedCache = distributedCache;
/// <inheritdoc />
[Obsolete("Scheduled for removal in Umbraco 18.")]
protected override void Handle(IEnumerable<ContentTypeChange<IContentType>> entities)
=> Handle(entities, new Dictionary<string, object?>());
/// <inheritdoc />
protected override void Handle(IEnumerable<ContentTypeChange<IContentType>> entities, IDictionary<string, object?> state)
=> _distributedCache.RefreshContentTypeCache(entities);
}

View File

@@ -1,5 +1,6 @@
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Notifications;
using Umbraco.Cms.Core.Services.Changes;
using Umbraco.Extensions;
namespace Umbraco.Cms.Core.Cache;
@@ -17,7 +18,12 @@ public sealed class DataTypeDeletedDistributedCacheNotificationHandler : Deleted
=> _distributedCache = distributedCache;
/// <inheritdoc />
[Obsolete("Scheduled for removal in Umbraco 18.")]
protected override void Handle(IEnumerable<IDataType> entities)
=> Handle(entities, new Dictionary<string, object?>());
/// <inheritdoc />
protected override void Handle(IEnumerable<IDataType> entities, IDictionary<string, object?> state)
{
_distributedCache.RemoveDataTypeCache(entities);
_distributedCache.RefreshValueEditorCache(entities);

View File

@@ -17,7 +17,12 @@ public sealed class DataTypeSavedDistributedCacheNotificationHandler : SavedDist
=> _distributedCache = distributedCache;
/// <inheritdoc />
[Obsolete("Scheduled for removal in Umbraco 18.")]
protected override void Handle(IEnumerable<IDataType> entities)
=> Handle(entities, new Dictionary<string, object?>());
/// <inheritdoc />
protected override void Handle(IEnumerable<IDataType> entities, IDictionary<string, object?> state)
{
_distributedCache.RefreshDataTypeCache(entities);
_distributedCache.RefreshValueEditorCache(entities);

View File

@@ -17,6 +17,11 @@ public sealed class DictionaryItemDeletedDistributedCacheNotificationHandler : D
=> _distributedCache = distributedCache;
/// <inheritdoc />
[Obsolete("Scheduled for removal in Umbraco 18.")]
protected override void Handle(IEnumerable<IDictionaryItem> entities)
=> Handle(entities, new Dictionary<string, object?>());
/// <inheritdoc />
protected override void Handle(IEnumerable<IDictionaryItem> entities, IDictionary<string, object?> state)
=> _distributedCache.RemoveDictionaryCache(entities);
}

View File

@@ -17,6 +17,11 @@ public sealed class DictionaryItemSavedDistributedCacheNotificationHandler : Sav
=> _distributedCache = distributedCache;
/// <inheritdoc />
[Obsolete("Scheduled for removal in Umbraco 18.")]
protected override void Handle(IEnumerable<IDictionaryItem> entities)
=> Handle(entities, new Dictionary<string, object?>());
/// <inheritdoc />
protected override void Handle(IEnumerable<IDictionaryItem> entities, IDictionary<string, object?> state)
=> _distributedCache.RefreshDictionaryCache(entities);
}

View File

@@ -17,6 +17,11 @@ public sealed class DomainDeletedDistributedCacheNotificationHandler : DeletedDi
=> _distributedCache = distributedCache;
/// <inheritdoc />
[Obsolete("Scheduled for removal in Umbraco 18.")]
protected override void Handle(IEnumerable<IDomain> entities)
=> Handle(entities, new Dictionary<string, object?>());
/// <inheritdoc />
protected override void Handle(IEnumerable<IDomain> entities, IDictionary<string, object?> state)
=> _distributedCache.RemoveDomainCache(entities);
}

View File

@@ -17,6 +17,11 @@ public sealed class DomainSavedDistributedCacheNotificationHandler : SavedDistri
=> _distributedCache = distributedCache;
/// <inheritdoc />
[Obsolete("Scheduled for removal in Umbraco 18.")]
protected override void Handle(IEnumerable<IDomain> entities)
=> Handle(entities, new Dictionary<string, object?>());
/// <inheritdoc />
protected override void Handle(IEnumerable<IDomain> entities, IDictionary<string, object?> state)
=> _distributedCache.RefreshDomainCache(entities);
}

View File

@@ -17,6 +17,11 @@ public sealed class LanguageDeletedDistributedCacheNotificationHandler : Deleted
=> _distributedCache = distributedCache;
/// <inheritdoc />
[Obsolete("Scheduled for removal in Umbraco 18.")]
protected override void Handle(IEnumerable<ILanguage> entities)
=> Handle(entities, new Dictionary<string, object?>());
/// <inheritdoc />
protected override void Handle(IEnumerable<ILanguage> entities, IDictionary<string, object?> state)
=> _distributedCache.RemoveLanguageCache(entities);
}

View File

@@ -17,6 +17,11 @@ public sealed class LanguageSavedDistributedCacheNotificationHandler : SavedDist
=> _distributedCache = distributedCache;
/// <inheritdoc />
[Obsolete("Scheduled for removal in Umbraco 18.")]
protected override void Handle(IEnumerable<ILanguage> entities)
=> Handle(entities, new Dictionary<string, object?>());
/// <inheritdoc />
protected override void Handle(IEnumerable<ILanguage> entities, IDictionary<string, object?> state)
=> _distributedCache.RefreshLanguageCache(entities);
}

View File

@@ -18,6 +18,11 @@ public sealed class MediaTreeChangeDistributedCacheNotificationHandler : TreeCha
=> _distributedCache = distributedCache;
/// <inheritdoc />
[Obsolete("Scheduled for removal in Umbraco 18.")]
protected override void Handle(IEnumerable<TreeChange<IMedia>> entities)
=> Handle(entities, new Dictionary<string, object?>());
/// <inheritdoc />
protected override void Handle(IEnumerable<TreeChange<IMedia>> entities, IDictionary<string, object?> state)
=> _distributedCache.RefreshMediaCache(entities);
}

View File

@@ -18,6 +18,11 @@ public sealed class MediaTypeChangedDistributedCacheNotificationHandler : Conten
=> _distributedCache = distributedCache;
/// <inheritdoc />
[Obsolete("Scheduled for removal in Umbraco 18.")]
protected override void Handle(IEnumerable<ContentTypeChange<IMediaType>> entities)
=> Handle(entities, new Dictionary<string, object?>());
/// <inheritdoc />
protected override void Handle(IEnumerable<ContentTypeChange<IMediaType>> entities, IDictionary<string, object?> state)
=> _distributedCache.RefreshContentTypeCache(entities);
}

View File

@@ -1,5 +1,6 @@
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Notifications;
using Umbraco.Cms.Core.Services.Changes;
using Umbraco.Extensions;
namespace Umbraco.Cms.Core.Cache;
@@ -17,6 +18,11 @@ public sealed class MemberDeletedDistributedCacheNotificationHandler : DeletedDi
=> _distributedCache = distributedCache;
/// <inheritdoc />
[Obsolete("Scheduled for removal in Umbraco 18.")]
protected override void Handle(IEnumerable<IMember> entities)
=> _distributedCache.RemoveMemberCache(entities);
=> Handle(entities, new Dictionary<string, object?>());
/// <inheritdoc />
protected override void Handle(IEnumerable<IMember> entities, IDictionary<string, object?> state)
=> _distributedCache.RemoveMemberCache(entities, state);
}

View File

@@ -17,6 +17,11 @@ public sealed class MemberGroupDeletedDistributedCacheNotificationHandler : Dele
=> _distributedCache = distributedCache;
/// <inheritdoc />
[Obsolete("Scheduled for removal in Umbraco 18.")]
protected override void Handle(IEnumerable<IMemberGroup> entities)
=> Handle(entities, new Dictionary<string, object?>());
/// <inheritdoc />
protected override void Handle(IEnumerable<IMemberGroup> entities, IDictionary<string, object?> state)
=> _distributedCache.RemoveMemberGroupCache(entities);
}

View File

@@ -1,4 +1,4 @@
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Notifications;
using Umbraco.Extensions;
@@ -17,6 +17,11 @@ public sealed class MemberGroupSavedDistributedCacheNotificationHandler : SavedD
=> _distributedCache = distributedCache;
/// <inheritdoc />
[Obsolete("Scheduled for removal in Umbraco 18.")]
protected override void Handle(IEnumerable<IMemberGroup> entities)
=> Handle(entities, new Dictionary<string, object?>());
/// <inheritdoc />
protected override void Handle(IEnumerable<IMemberGroup> entities, IDictionary<string, object?> state)
=> _distributedCache.RefreshMemberGroupCache(entities);
}

View File

@@ -17,6 +17,11 @@ public sealed class MemberSavedDistributedCacheNotificationHandler : SavedDistri
=> _distributedCache = distributedCache;
/// <inheritdoc />
[Obsolete("Scheduled for removal in Umbraco 18.")]
protected override void Handle(IEnumerable<IMember> entities)
=> _distributedCache.RefreshMemberCache(entities);
=> Handle(entities, new Dictionary<string, object?>());
/// <inheritdoc />
protected override void Handle(IEnumerable<IMember> entities, IDictionary<string, object?> state)
=> _distributedCache.RefreshMemberCache(entities, state);
}

View File

@@ -19,6 +19,11 @@ public sealed class MemberTypeChangedDistributedCacheNotificationHandler : Conte
=> _distributedCache = distributedCache;
/// <inheritdoc />
[Obsolete("Scheduled for removal in Umbraco 18.")]
protected override void Handle(IEnumerable<ContentTypeChange<IMemberType>> entities)
=> Handle(entities, new Dictionary<string, object?>());
/// <inheritdoc />
protected override void Handle(IEnumerable<ContentTypeChange<IMemberType>> entities, IDictionary<string, object?> state)
=> _distributedCache.RefreshContentTypeCache(entities);
}

View File

@@ -1,5 +1,6 @@
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Notifications;
using Umbraco.Cms.Core.Services.Changes;
using Umbraco.Extensions;
namespace Umbraco.Cms.Core.Cache;
@@ -17,6 +18,11 @@ public sealed class PublicAccessEntryDeletedDistributedCacheNotificationHandler
=> _distributedCache = distributedCache;
/// <inheritdoc />
[Obsolete("Scheduled for removal in Umbraco 18.")]
protected override void Handle(IEnumerable<PublicAccessEntry> entities)
=> Handle(entities, new Dictionary<string, object?>());
/// <inheritdoc />
protected override void Handle(IEnumerable<PublicAccessEntry> entities, IDictionary<string, object?> state)
=> _distributedCache.RefreshPublicAccess();
}

View File

@@ -17,6 +17,11 @@ public sealed class PublicAccessEntrySavedDistributedCacheNotificationHandler :
=> _distributedCache = distributedCache;
/// <inheritdoc />
[Obsolete("Scheduled for removal in Umbraco 18.")]
protected override void Handle(IEnumerable<PublicAccessEntry> entities)
=> Handle(entities, new Dictionary<string, object?>());
/// <inheritdoc />
protected override void Handle(IEnumerable<PublicAccessEntry> entities, IDictionary<string, object?> state)
=> _distributedCache.RefreshPublicAccess();
}

View File

@@ -17,6 +17,11 @@ public sealed class RelationTypeDeletedDistributedCacheNotificationHandler : Del
=> _distributedCache = distributedCache;
/// <inheritdoc />
[Obsolete("Scheduled for removal in Umbraco 18.")]
protected override void Handle(IEnumerable<IRelationType> entities)
=> Handle(entities, new Dictionary<string, object?>());
/// <inheritdoc />
protected override void Handle(IEnumerable<IRelationType> entities, IDictionary<string, object?> state)
=> _distributedCache.RemoveRelationTypeCache(entities);
}

View File

@@ -17,6 +17,11 @@ public sealed class RelationTypeSavedDistributedCacheNotificationHandler : Saved
=> _distributedCache = distributedCache;
/// <inheritdoc />
[Obsolete("Scheduled for removal in Umbraco 18.")]
protected override void Handle(IEnumerable<IRelationType> entities)
=> Handle(entities, new Dictionary<string, object?>());
/// <inheritdoc />
protected override void Handle(IEnumerable<IRelationType> entities, IDictionary<string, object?> state)
=> _distributedCache.RefreshRelationTypeCache(entities);
}

View File

@@ -17,6 +17,11 @@ public sealed class TemplateDeletedDistributedCacheNotificationHandler : Deleted
=> _distributedCache = distributedCache;
/// <inheritdoc />
[Obsolete("Scheduled for removal in Umbraco 18.")]
protected override void Handle(IEnumerable<ITemplate> entities)
=> Handle(entities, new Dictionary<string, object?>());
/// <inheritdoc />
protected override void Handle(IEnumerable<ITemplate> entities, IDictionary<string, object?> state)
=> _distributedCache.RemoveTemplateCache(entities);
}

View File

@@ -17,6 +17,11 @@ public sealed class TemplateSavedDistributedCacheNotificationHandler : SavedDist
=> _distributedCache = distributedCache;
/// <inheritdoc />
[Obsolete("Scheduled for removal in Umbraco 18.")]
protected override void Handle(IEnumerable<ITemplate> entities)
=> Handle(entities, new Dictionary<string, object?>());
/// <inheritdoc />
protected override void Handle(IEnumerable<ITemplate> entities, IDictionary<string, object?> state)
=> _distributedCache.RefreshTemplateCache(entities);
}

View File

@@ -1,3 +1,4 @@
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Membership;
using Umbraco.Cms.Core.Notifications;
using Umbraco.Extensions;
@@ -17,6 +18,11 @@ public sealed class UserDeletedDistributedCacheNotificationHandler : DeletedDist
=> _distributedCache = distributedCache;
/// <inheritdoc />
[Obsolete("Scheduled for removal in Umbraco 18.")]
protected override void Handle(IEnumerable<IUser> entities)
=> Handle(entities, new Dictionary<string, object?>());
/// <inheritdoc />
protected override void Handle(IEnumerable<IUser> entities, IDictionary<string, object?> state)
=> _distributedCache.RemoveUserCache(entities);
}

View File

@@ -17,6 +17,11 @@ public sealed class UserGroupDeletedDistributedCacheNotificationHandler : Delete
=> _distributedCache = distributedCache;
/// <inheritdoc />
[Obsolete("Scheduled for removal in Umbraco 18.")]
protected override void Handle(IEnumerable<IUserGroup> entities)
=> Handle(entities, new Dictionary<string, object?>());
/// <inheritdoc />
protected override void Handle(IEnumerable<IUserGroup> entities, IDictionary<string, object?> state)
=> _distributedCache.RemoveUserGroupCache(entities);
}

View File

@@ -22,6 +22,11 @@ public sealed class UserGroupWithUsersSavedDistributedCacheNotificationHandler :
=> notification.SavedEntities.Select(x => x.UserGroup);
/// <inheritdoc />
[Obsolete("Scheduled for removal in Umbraco 18.")]
protected override void Handle(IEnumerable<IUserGroup> entities)
=> Handle(entities, new Dictionary<string, object?>());
/// <inheritdoc />
protected override void Handle(IEnumerable<IUserGroup> entities, IDictionary<string, object?> state)
=> _distributedCache.RefreshUserGroupCache(entities);
}

View File

@@ -17,6 +17,11 @@ public sealed class UserSavedDistributedCacheNotificationHandler : SavedDistribu
=> _distributedCache = distributedCache;
/// <inheritdoc />
[Obsolete("Scheduled for removal in Umbraco 18.")]
protected override void Handle(IEnumerable<IUser> entities)
=> Handle(entities, new Dictionary<string, object?>());
/// <inheritdoc />
protected override void Handle(IEnumerable<IUser> entities, IDictionary<string, object?> state)
=> _distributedCache.RefreshUserCache(entities);
}