diff --git a/src/Umbraco.Infrastructure/Cache/DistributedCacheBinder_Handlers.cs b/src/Umbraco.Infrastructure/Cache/DistributedCacheBinder_Handlers.cs index de75ac0905..919b39c22d 100644 --- a/src/Umbraco.Infrastructure/Cache/DistributedCacheBinder_Handlers.cs +++ b/src/Umbraco.Infrastructure/Cache/DistributedCacheBinder_Handlers.cs @@ -23,7 +23,9 @@ namespace Umbraco.Cms.Core.Cache INotificationHandler, INotificationHandler, INotificationHandler, - INotificationHandler + INotificationHandler, + INotificationHandler, + INotificationHandler { private List _unbinders; @@ -109,10 +111,6 @@ namespace Umbraco.Cms.Core.Cache () => MemberService.Saved -= MemberService_Saved); Bind(() => MemberService.Deleted += MemberService_Deleted, () => MemberService.Deleted -= MemberService_Deleted); - Bind(() => MemberGroupService.Saved += MemberGroupService_Saved, - () => MemberGroupService.Saved -= MemberGroupService_Saved); - Bind(() => MemberGroupService.Deleted += MemberGroupService_Deleted, - () => MemberGroupService.Deleted -= MemberGroupService_Deleted); // bind to media events - handles all media changes Bind(() => MediaService.TreeChanged += MediaService_TreeChanged, @@ -404,19 +402,27 @@ namespace Umbraco.Cms.Core.Cache #region MemberGroupService - private void MemberGroupService_Deleted(IMemberGroupService sender, DeleteEventArgs e) + /// + /// Fires when a member group is deleted + /// + /// + public void Handle(MemberGroupDeletedNotification notification) { - foreach (var m in e.DeletedEntities.ToArray()) + foreach (IMemberGroup entity in notification.DeletedEntities) { - _distributedCache.RemoveMemberGroupCache(m.Id); + _distributedCache.RemoveMemberGroupCache(entity.Id); } } - private void MemberGroupService_Saved(IMemberGroupService sender, SaveEventArgs e) + /// + /// Fires when a member group is saved + /// + /// + public void Handle(MemberGroupSavedNotification notification) { - foreach (var m in e.SavedEntities.ToArray()) + foreach (IMemberGroup entity in notification.SavedEntities) { - _distributedCache.RemoveMemberGroupCache(m.Id); + _distributedCache.RemoveMemberGroupCache(entity.Id); } } diff --git a/src/Umbraco.Infrastructure/Compose/PublicAccessComposer.cs b/src/Umbraco.Infrastructure/Compose/PublicAccessComposer.cs index 71e48c44d1..c4dcfeb041 100644 --- a/src/Umbraco.Infrastructure/Compose/PublicAccessComposer.cs +++ b/src/Umbraco.Infrastructure/Compose/PublicAccessComposer.cs @@ -1,10 +1,17 @@ -using Umbraco.Cms.Core.Composing; +using Umbraco.Cms.Core.Composing; +using Umbraco.Cms.Core.DependencyInjection; +using Umbraco.Cms.Infrastructure.Services.Notifications; namespace Umbraco.Cms.Core.Compose { /// /// Used to ensure that the public access data file is kept up to date properly /// - public sealed class PublicAccessComposer : ComponentComposer, ICoreComposer - { } + public sealed class PublicAccessComposer : ICoreComposer + { + public void Compose(IUmbracoBuilder builder) => + builder + .AddNotificationHandler() + .AddNotificationHandler(); + } } diff --git a/src/Umbraco.Infrastructure/Compose/PublicAccessComponent.cs b/src/Umbraco.Infrastructure/Compose/PublicAccessHandler.cs similarity index 57% rename from src/Umbraco.Infrastructure/Compose/PublicAccessComponent.cs rename to src/Umbraco.Infrastructure/Compose/PublicAccessHandler.cs index b8c60c9d8a..b9ded9aff8 100644 --- a/src/Umbraco.Infrastructure/Compose/PublicAccessComponent.cs +++ b/src/Umbraco.Infrastructure/Compose/PublicAccessHandler.cs @@ -1,34 +1,29 @@ -using System; -using Umbraco.Cms.Core.Composing; +using System; +using System.Collections.Generic; using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Services; -using Umbraco.Cms.Core.Services.Implement; +using Umbraco.Cms.Infrastructure.Services.Notifications; using Umbraco.Extensions; namespace Umbraco.Cms.Core.Compose { - public sealed class PublicAccessComponent : IComponent + public sealed class PublicAccessHandler : + INotificationHandler, + INotificationHandler { private readonly IPublicAccessService _publicAccessService; - public PublicAccessComponent(IPublicAccessService publicAccessService) - { + + public PublicAccessHandler(IPublicAccessService publicAccessService) => _publicAccessService = publicAccessService ?? throw new ArgumentNullException(nameof(publicAccessService)); - } - public void Initialize() - { - MemberGroupService.Saved += MemberGroupService_Saved; - } + public void Handle(MemberGroupSavedNotification notification) => Handle(notification.SavedEntities); - public void Terminate() - { - MemberGroupService.Saved -= MemberGroupService_Saved; - } + public void Handle(MemberGroupDeletedNotification notification) => Handle(notification.DeletedEntities); - private void MemberGroupService_Saved(IMemberGroupService sender, SaveEventArgs e) + private void Handle(IEnumerable affectedEntities) { - foreach (var grp in e.SavedEntities) + foreach (var grp in affectedEntities) { //check if the name has changed if (grp.AdditionalData.ContainsKey("previousName") diff --git a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MemberGroupRepository.cs b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MemberGroupRepository.cs index abce17a331..2d73413563 100644 --- a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MemberGroupRepository.cs +++ b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MemberGroupRepository.cs @@ -12,15 +12,18 @@ using Umbraco.Cms.Core.Scoping; using Umbraco.Cms.Infrastructure.Persistence.Dtos; using Umbraco.Cms.Infrastructure.Persistence.Factories; using Umbraco.Cms.Infrastructure.Persistence.Querying; +using Umbraco.Cms.Infrastructure.Services.Notifications; using Umbraco.Extensions; namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement { internal class MemberGroupRepository : EntityRepositoryBase, IMemberGroupRepository { - public MemberGroupRepository(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger) - : base(scopeAccessor, cache, logger) - { } + private readonly IEventMessagesFactory _eventMessagesFactory; + + public MemberGroupRepository(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger, IEventMessagesFactory eventMessagesFactory) + : base(scopeAccessor, cache, logger) => + _eventMessagesFactory = eventMessagesFactory; protected override IMemberGroup PerformGet(int id) { @@ -156,10 +159,14 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement }; PersistNewItem(grp); - if (AmbientScope.Events.DispatchCancelable(SavingMemberGroup, this, new SaveEventArgs(grp))) + var evtMsgs = _eventMessagesFactory.Get(); + if (AmbientScope.Notifications.PublishCancelable(new MemberGroupSavingNotification(grp, evtMsgs))) + { return null; + } + + AmbientScope.Notifications.Publish(new MemberGroupSavedNotification(grp, evtMsgs)); - AmbientScope.Events.Dispatch(SavedMemberGroup, this, new SaveEventArgs(grp)); return grp; } @@ -240,13 +247,16 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement var missingRoles = roleNames.Except(existingRoles, StringComparer.CurrentCultureIgnoreCase); var missingGroups = missingRoles.Select(x => new MemberGroup {Name = x}).ToArray(); - if (AmbientScope.Events.DispatchCancelable(SavingMemberGroup, this, new SaveEventArgs(missingGroups))) + var evtMsgs = _eventMessagesFactory.Get(); + if (AmbientScope.Notifications.PublishCancelable(new MemberGroupSavingNotification(missingGroups, evtMsgs))) + { return; + } foreach (var m in missingGroups) PersistNewItem(m); - AmbientScope.Events.Dispatch(SavedMemberGroup, this, new SaveEventArgs(missingGroups)); + AmbientScope.Notifications.Publish(new MemberGroupSavedNotification(missingGroups, evtMsgs)); //now go get all the dto's for roles with these role names var rolesForNames = Database.Fetch(existingSql).ToArray(); @@ -310,17 +320,5 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement [Column("MemberGroup")] public int MemberGroupId { get; set; } } - - // TODO: understand why we need these two repository-level events, move them back to service - - /// - /// Occurs before Save - /// - internal static event TypedEventHandler> SavingMemberGroup; - - /// - /// Occurs after Save - /// - internal static event TypedEventHandler> SavedMemberGroup; } } diff --git a/src/Umbraco.Infrastructure/Services/Implement/MemberGroupService.cs b/src/Umbraco.Infrastructure/Services/Implement/MemberGroupService.cs index 5e6138980a..ac3366a065 100644 --- a/src/Umbraco.Infrastructure/Services/Implement/MemberGroupService.cs +++ b/src/Umbraco.Infrastructure/Services/Implement/MemberGroupService.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Microsoft.Extensions.Logging; @@ -6,7 +6,7 @@ using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Persistence.Repositories; using Umbraco.Cms.Core.Scoping; -using Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement; +using Umbraco.Cms.Infrastructure.Services.Notifications; namespace Umbraco.Cms.Core.Services.Implement { @@ -16,30 +16,8 @@ namespace Umbraco.Cms.Core.Services.Implement public MemberGroupService(IScopeProvider provider, ILoggerFactory loggerFactory, IEventMessagesFactory eventMessagesFactory, IMemberGroupRepository memberGroupRepository) - : base(provider, loggerFactory, eventMessagesFactory) - { + : base(provider, loggerFactory, eventMessagesFactory) => _memberGroupRepository = memberGroupRepository; - //Proxy events! - MemberGroupRepository.SavedMemberGroup += MemberGroupRepository_SavedMemberGroup; - MemberGroupRepository.SavingMemberGroup += MemberGroupRepository_SavingMemberGroup; - } - - #region Proxy event handlers - - void MemberGroupRepository_SavingMemberGroup(IMemberGroupRepository sender, SaveEventArgs e) - { - if (Saving.IsRaisedEventCancelled(new SaveEventArgs(e.SavedEntities), this)) - e.Cancel = true; - } - - void MemberGroupRepository_SavedMemberGroup(IMemberGroupRepository sender, SaveEventArgs e) - { - // same as above! - - Saved.RaiseEvent(new SaveEventArgs(e.SavedEntities, false), this); - } - - #endregion public IEnumerable GetAll() { @@ -92,10 +70,13 @@ namespace Umbraco.Cms.Core.Services.Implement { throw new InvalidOperationException("The name of a MemberGroup can not be empty"); } + + var evtMsgs = EventMessagesFactory.Get(); + using (var scope = ScopeProvider.CreateScope()) { - var saveEventArgs = new SaveEventArgs(memberGroup); - if (raiseEvents && scope.Events.DispatchCancelable(Saving, this, saveEventArgs)) + var savingNotification = new MemberGroupSavingNotification(memberGroup, evtMsgs); + if (raiseEvents && scope.Notifications.PublishCancelable(savingNotification)) { scope.Complete(); return; @@ -106,18 +87,19 @@ namespace Umbraco.Cms.Core.Services.Implement if (raiseEvents) { - saveEventArgs.CanCancel = false; - scope.Events.Dispatch(Saved, this, saveEventArgs); + scope.Notifications.Publish(new MemberGroupSavedNotification(memberGroup, evtMsgs).WithStateFrom(savingNotification)); } } } public void Delete(IMemberGroup memberGroup) { + var evtMsgs = EventMessagesFactory.Get(); + using (var scope = ScopeProvider.CreateScope()) { - var deleteEventArgs = new DeleteEventArgs(memberGroup); - if (scope.Events.DispatchCancelable(Deleting, this, deleteEventArgs)) + var deletingNotification = new MemberGroupDeletingNotification(memberGroup, evtMsgs); + if (scope.Notifications.PublishCancelable(deletingNotification)) { scope.Complete(); return; @@ -125,35 +107,9 @@ namespace Umbraco.Cms.Core.Services.Implement _memberGroupRepository.Delete(memberGroup); scope.Complete(); - deleteEventArgs.CanCancel = false; - scope.Events.Dispatch(Deleted, this, deleteEventArgs); + + scope.Notifications.Publish(new MemberGroupDeletedNotification(memberGroup, evtMsgs).WithStateFrom(deletingNotification)); } } - - /// - /// Occurs before Delete of a member group - /// - public static event TypedEventHandler> Deleting; - - /// - /// Occurs after Delete of a member group - /// - public static event TypedEventHandler> Deleted; - - /// - /// Occurs before Save of a member group - /// - /// - /// We need to proxy these events because the events need to take place at the repo level - /// - public static event TypedEventHandler> Saving; - - /// - /// Occurs after Save of a member group - /// - /// - /// We need to proxy these events because the events need to take place at the repo level - /// - public static event TypedEventHandler> Saved; } } diff --git a/src/Umbraco.Infrastructure/Services/Notifications/MemberGroupDeletedNotification.cs b/src/Umbraco.Infrastructure/Services/Notifications/MemberGroupDeletedNotification.cs new file mode 100644 index 0000000000..1441344ec5 --- /dev/null +++ b/src/Umbraco.Infrastructure/Services/Notifications/MemberGroupDeletedNotification.cs @@ -0,0 +1,12 @@ +using Umbraco.Cms.Core.Events; +using Umbraco.Cms.Core.Models; + +namespace Umbraco.Cms.Infrastructure.Services.Notifications +{ + public class MemberGroupDeletedNotification : DeletedNotification + { + public MemberGroupDeletedNotification(IMemberGroup target, EventMessages messages) : base(target, messages) + { + } + } +} diff --git a/src/Umbraco.Infrastructure/Services/Notifications/MemberGroupDeletingNotification.cs b/src/Umbraco.Infrastructure/Services/Notifications/MemberGroupDeletingNotification.cs new file mode 100644 index 0000000000..34e4140752 --- /dev/null +++ b/src/Umbraco.Infrastructure/Services/Notifications/MemberGroupDeletingNotification.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using Umbraco.Cms.Core.Events; +using Umbraco.Cms.Core.Models; + +namespace Umbraco.Cms.Infrastructure.Services.Notifications +{ + public class MemberGroupDeletingNotification : DeletingNotification + { + public MemberGroupDeletingNotification(IMemberGroup target, EventMessages messages) : base(target, messages) + { + } + + public MemberGroupDeletingNotification(IEnumerable target, EventMessages messages) : base(target, messages) + { + } + } +} diff --git a/src/Umbraco.Infrastructure/Services/Notifications/MemberGroupSavedNotification.cs b/src/Umbraco.Infrastructure/Services/Notifications/MemberGroupSavedNotification.cs new file mode 100644 index 0000000000..f9af9806ef --- /dev/null +++ b/src/Umbraco.Infrastructure/Services/Notifications/MemberGroupSavedNotification.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using Umbraco.Cms.Core.Events; +using Umbraco.Cms.Core.Models; + +namespace Umbraco.Cms.Infrastructure.Services.Notifications +{ + public class MemberGroupSavedNotification : SavedNotification + { + public MemberGroupSavedNotification(IMemberGroup target, EventMessages messages) : base(target, messages) + { + } + + public MemberGroupSavedNotification(IEnumerable target, EventMessages messages) : base(target, messages) + { + } + } +} diff --git a/src/Umbraco.Infrastructure/Services/Notifications/MemberGroupSavingNotification.cs b/src/Umbraco.Infrastructure/Services/Notifications/MemberGroupSavingNotification.cs new file mode 100644 index 0000000000..67e03c2268 --- /dev/null +++ b/src/Umbraco.Infrastructure/Services/Notifications/MemberGroupSavingNotification.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using Umbraco.Cms.Core.Events; +using Umbraco.Cms.Core.Models; + +namespace Umbraco.Cms.Infrastructure.Services.Notifications +{ + public class MemberGroupSavingNotification : SavingNotification + { + public MemberGroupSavingNotification(IMemberGroup target, EventMessages messages) : base(target, messages) + { + } + + public MemberGroupSavingNotification(IEnumerable target, EventMessages messages) : base(target, messages) + { + } + } +} diff --git a/src/Umbraco.Tests.Integration/Cache/DistributedCacheBinderTests.cs b/src/Umbraco.Tests.Integration/Cache/DistributedCacheBinderTests.cs index 6a263cb6ae..1da6261bdc 100644 --- a/src/Umbraco.Tests.Integration/Cache/DistributedCacheBinderTests.cs +++ b/src/Umbraco.Tests.Integration/Cache/DistributedCacheBinderTests.cs @@ -73,9 +73,6 @@ namespace Umbraco.Cms.Tests.Integration.Cache new EventDefinition>(null, MemberService, new SaveEventArgs(Enumerable.Empty())), new EventDefinition>(null, MemberService, new DeleteEventArgs(Enumerable.Empty())), - new EventDefinition>(null, MemberGroupService, new SaveEventArgs(Enumerable.Empty())), - new EventDefinition>(null, MemberGroupService, new DeleteEventArgs(Enumerable.Empty())), - // not managed //new EventDefinition>(null, ContentService, new SaveEventArgs(Enumerable.Empty()), "SavedBlueprint"), //new EventDefinition>(null, ContentService, new DeleteEventArgs(Enumerable.Empty()), "DeletedBlueprint"), diff --git a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/ScopedRepositoryTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/ScopedRepositoryTests.cs index 61334940e1..43a3e91b35 100644 --- a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/ScopedRepositoryTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/ScopedRepositoryTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Umbraco. +// Copyright (c) Umbraco. // See LICENSE for more details. using System.Collections.Generic; @@ -55,7 +55,9 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Scoping .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() - .AddNotificationHandler(); + .AddNotificationHandler() + .AddNotificationHandler() + .AddNotificationHandler(); builder.AddNotificationHandler(); }