diff --git a/src/Umbraco.Infrastructure/Cache/DistributedCacheBinder_Handlers.cs b/src/Umbraco.Infrastructure/Cache/DistributedCacheBinder_Handlers.cs
index 1aa4906029..de75ac0905 100644
--- a/src/Umbraco.Infrastructure/Cache/DistributedCacheBinder_Handlers.cs
+++ b/src/Umbraco.Infrastructure/Cache/DistributedCacheBinder_Handlers.cs
@@ -11,6 +11,7 @@ using Umbraco.Cms.Core.Models.Membership;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.Changes;
using Umbraco.Cms.Core.Services.Implement;
+using Umbraco.Cms.Infrastructure.Services.Notifications;
using Umbraco.Extensions;
namespace Umbraco.Cms.Core.Cache
@@ -18,7 +19,11 @@ namespace Umbraco.Cms.Core.Cache
///
/// Default implementation.
///
- public partial class DistributedCacheBinder
+ public partial class DistributedCacheBinder :
+ INotificationHandler,
+ INotificationHandler,
+ INotificationHandler,
+ INotificationHandler
{
private List _unbinders;
@@ -61,12 +66,6 @@ namespace Umbraco.Cms.Core.Cache
Bind(() => UserService.UserGroupPermissionsAssigned += UserService_UserGroupPermissionsAssigned,
() => UserService.UserGroupPermissionsAssigned -= UserService_UserGroupPermissionsAssigned);
- // bind to dictionary events
- Bind(() => LocalizationService.DeletedDictionaryItem += LocalizationService_DeletedDictionaryItem,
- () => LocalizationService.DeletedDictionaryItem -= LocalizationService_DeletedDictionaryItem);
- Bind(() => LocalizationService.SavedDictionaryItem += LocalizationService_SavedDictionaryItem,
- () => LocalizationService.SavedDictionaryItem -= LocalizationService_SavedDictionaryItem);
-
// bind to data type events
Bind(() => DataTypeService.Deleted += DataTypeService_Deleted,
() => DataTypeService.Deleted -= DataTypeService_Deleted);
@@ -85,12 +84,6 @@ namespace Umbraco.Cms.Core.Cache
Bind(() => DomainService.Deleted += DomainService_Deleted,
() => DomainService.Deleted -= DomainService_Deleted);
- // bind to language events
- Bind(() => LocalizationService.SavedLanguage += LocalizationService_SavedLanguage,
- () => LocalizationService.SavedLanguage -= LocalizationService_SavedLanguage);
- Bind(() => LocalizationService.DeletedLanguage += LocalizationService_DeletedLanguage,
- () => LocalizationService.DeletedLanguage -= LocalizationService_DeletedLanguage);
-
// bind to content type events
Bind(() => ContentTypeService.Changed += ContentTypeService_Changed,
() => ContentTypeService.Changed -= ContentTypeService_Changed);
@@ -196,17 +189,20 @@ namespace Umbraco.Cms.Core.Cache
#endregion
#region LocalizationService / Dictionary
-
- private void LocalizationService_SavedDictionaryItem(ILocalizationService sender, SaveEventArgs e)
+ public void Handle(DictionaryItemSavedNotification notification)
{
- foreach (var entity in e.SavedEntities)
+ foreach (IDictionaryItem entity in notification.SavedEntities)
+ {
_distributedCache.RefreshDictionaryCache(entity.Id);
+ }
}
- private void LocalizationService_DeletedDictionaryItem(ILocalizationService sender, DeleteEventArgs e)
+ public void Handle(DictionaryItemDeletedNotification notification)
{
- foreach (var entity in e.DeletedEntities)
+ foreach (IDictionaryItem entity in notification.DeletedEntities)
+ {
_distributedCache.RemoveDictionaryCache(entity.Id);
+ }
}
#endregion
@@ -248,23 +244,25 @@ namespace Umbraco.Cms.Core.Cache
///
/// Fires when a language is deleted
///
- ///
- ///
- private void LocalizationService_DeletedLanguage(ILocalizationService sender, DeleteEventArgs e)
+ ///
+ public void Handle(LanguageDeletedNotification notification)
{
- foreach (var entity in e.DeletedEntities)
+ foreach (ILanguage entity in notification.DeletedEntities)
+ {
_distributedCache.RemoveLanguageCache(entity);
+ }
}
///
/// Fires when a language is saved
///
- ///
- ///
- private void LocalizationService_SavedLanguage(ILocalizationService sender, SaveEventArgs e)
+ ///
+ public void Handle(LanguageSavedNotification notification)
{
- foreach (var entity in e.SavedEntities)
+ foreach (ILanguage entity in notification.SavedEntities)
+ {
_distributedCache.RefreshLanguageCache(entity);
+ }
}
#endregion
diff --git a/src/Umbraco.Infrastructure/Compose/NotificationsComposer.cs b/src/Umbraco.Infrastructure/Compose/NotificationsComposer.cs
index c760c33b71..2e3403e3dd 100644
--- a/src/Umbraco.Infrastructure/Compose/NotificationsComposer.cs
+++ b/src/Umbraco.Infrastructure/Compose/NotificationsComposer.cs
@@ -1,6 +1,7 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
+using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Events;
@@ -62,6 +63,13 @@ namespace Umbraco.Cms.Core.Compose
.AddNotificationHandler()
.AddNotificationHandler()
.AddNotificationHandler();
+
+ // Add notification handlers for DistributedCache
+ builder
+ .AddNotificationHandler()
+ .AddNotificationHandler()
+ .AddNotificationHandler()
+ .AddNotificationHandler();
}
}
}
diff --git a/src/Umbraco.Infrastructure/Services/Implement/LocalizationService.cs b/src/Umbraco.Infrastructure/Services/Implement/LocalizationService.cs
index f4072ccfb7..b8c36f1ed9 100644
--- a/src/Umbraco.Infrastructure/Services/Implement/LocalizationService.cs
+++ b/src/Umbraco.Infrastructure/Services/Implement/LocalizationService.cs
@@ -18,7 +18,6 @@ namespace Umbraco.Cms.Core.Services.Implement
{
private readonly IDictionaryRepository _dictionaryRepository;
private readonly ILanguageRepository _languageRepository;
- private readonly IEventAggregator _eventAggregator;
private readonly IAuditRepository _auditRepository;
public LocalizationService(
@@ -27,14 +26,12 @@ namespace Umbraco.Cms.Core.Services.Implement
IEventMessagesFactory eventMessagesFactory,
IDictionaryRepository dictionaryRepository,
IAuditRepository auditRepository,
- ILanguageRepository languageRepository,
- IEventAggregator eventAggregator)
+ ILanguageRepository languageRepository)
: base(provider, loggerFactory, eventMessagesFactory)
{
_dictionaryRepository = dictionaryRepository;
_auditRepository = auditRepository;
_languageRepository = languageRepository;
- _eventAggregator = eventAggregator;
}
///
@@ -101,7 +98,7 @@ namespace Umbraco.Cms.Core.Services.Implement
EventMessages eventMessages = EventMessagesFactory.Get();
var savingNotification = new DictionaryItemSavingNotification(item, eventMessages);
- if (_eventAggregator.PublishCancelable(savingNotification))
+ if (scope.Notifications.PublishCancelable(savingNotification))
{
scope.Complete();
return item;
@@ -111,7 +108,7 @@ namespace Umbraco.Cms.Core.Services.Implement
// ensure the lazy Language callback is assigned
EnsureDictionaryItemLanguageCallback(item);
- _eventAggregator.Publish(new DictionaryItemSavedNotification(item, eventMessages).WithStateFrom(savingNotification));
+ scope.Notifications.Publish(new DictionaryItemSavedNotification(item, eventMessages).WithStateFrom(savingNotification));
scope.Complete();
@@ -244,7 +241,7 @@ namespace Umbraco.Cms.Core.Services.Implement
{
EventMessages eventMessages = EventMessagesFactory.Get();
var savingNotification = new DictionaryItemSavingNotification(dictionaryItem, eventMessages);
- if (_eventAggregator.PublishCancelable(savingNotification))
+ if (scope.Notifications.PublishCancelable(savingNotification))
{
scope.Complete();
return;
@@ -256,7 +253,7 @@ namespace Umbraco.Cms.Core.Services.Implement
// ensure the lazy Language callback is assigned
EnsureDictionaryItemLanguageCallback(dictionaryItem);
- _eventAggregator.Publish(new DictionaryItemSavedNotification(dictionaryItem, eventMessages).WithStateFrom(savingNotification));
+ scope.Notifications.Publish(new DictionaryItemSavedNotification(dictionaryItem, eventMessages).WithStateFrom(savingNotification));
Audit(AuditType.Save, "Save DictionaryItem", userId, dictionaryItem.Id, "DictionaryItem");
scope.Complete();
@@ -275,14 +272,14 @@ namespace Umbraco.Cms.Core.Services.Implement
{
EventMessages eventMessages = EventMessagesFactory.Get();
var deletingNotification = new DictionaryItemDeletingNotification(dictionaryItem, eventMessages);
- if (_eventAggregator.PublishCancelable(deletingNotification))
+ if (scope.Notifications.PublishCancelable(deletingNotification))
{
scope.Complete();
return;
}
_dictionaryRepository.Delete(dictionaryItem);
- _eventAggregator.Publish(new DictionaryItemDeletedNotification(dictionaryItem, eventMessages).WithStateFrom(deletingNotification));
+ scope.Notifications.Publish(new DictionaryItemDeletedNotification(dictionaryItem, eventMessages).WithStateFrom(deletingNotification));
Audit(AuditType.Delete, "Delete DictionaryItem", userId, dictionaryItem.Id, "DictionaryItem");
@@ -388,14 +385,14 @@ namespace Umbraco.Cms.Core.Services.Implement
EventMessages eventMessages = EventMessagesFactory.Get();
var savingNotification = new LanguageSavingNotification(language, eventMessages);
- if (_eventAggregator.PublishCancelable(savingNotification))
+ if (scope.Notifications.PublishCancelable(savingNotification))
{
scope.Complete();
return;
}
_languageRepository.Save(language);
- _eventAggregator.Publish(new LanguageSavedNotification(language, eventMessages).WithStateFrom(savingNotification));
+ scope.Notifications.Publish(new LanguageSavedNotification(language, eventMessages).WithStateFrom(savingNotification));
Audit(AuditType.Save, "Save Language", userId, language.Id, ObjectTypes.GetName(UmbracoObjectTypes.Language));
@@ -431,7 +428,7 @@ namespace Umbraco.Cms.Core.Services.Implement
EventMessages eventMessages = EventMessagesFactory.Get();
var deletingLanguageNotification = new LanguageDeletingNotification(language, eventMessages);
- if (_eventAggregator.PublishCancelable(deletingLanguageNotification))
+ if (scope.Notifications.PublishCancelable(deletingLanguageNotification))
{
scope.Complete();
return;
@@ -440,7 +437,7 @@ namespace Umbraco.Cms.Core.Services.Implement
// NOTE: Other than the fall-back language, there aren't any other constraints in the db, so possible references aren't deleted
_languageRepository.Delete(language);
- _eventAggregator.Publish(new LanguageDeletedNotification(language, eventMessages).WithStateFrom(deletingLanguageNotification));
+ scope.Notifications.Publish(new LanguageDeletedNotification(language, eventMessages).WithStateFrom(deletingLanguageNotification));
Audit(AuditType.Delete, "Delete Language", userId, language.Id, ObjectTypes.GetName(UmbracoObjectTypes.Language));
scope.Complete();
@@ -475,47 +472,5 @@ namespace Umbraco.Cms.Core.Services.Implement
return _dictionaryRepository.GetDictionaryItemKeyMap();
}
}
-
- #region Events
- ///
- /// Occurs before Delete
- ///
- public static event TypedEventHandler> DeletingLanguage;
-
- ///
- /// Occurs after Delete
- ///
- public static event TypedEventHandler> DeletedLanguage;
-
- ///
- /// Occurs before Delete
- ///
- public static event TypedEventHandler> DeletingDictionaryItem;
-
- ///
- /// Occurs after Delete
- ///
- public static event TypedEventHandler> DeletedDictionaryItem;
-
- ///
- /// Occurs before Save
- ///
- public static event TypedEventHandler> SavingDictionaryItem;
-
- ///
- /// Occurs after Save
- ///
- public static event TypedEventHandler> SavedDictionaryItem;
-
- ///
- /// Occurs before Save
- ///
- public static event TypedEventHandler> SavingLanguage;
-
- ///
- /// Occurs after Save
- ///
- public static event TypedEventHandler> SavedLanguage;
- #endregion
}
}
diff --git a/src/Umbraco.PublishedCache.NuCache/Compose/NotificationsComposer.cs b/src/Umbraco.PublishedCache.NuCache/Compose/NotificationsComposer.cs
new file mode 100644
index 0000000000..df84759793
--- /dev/null
+++ b/src/Umbraco.PublishedCache.NuCache/Compose/NotificationsComposer.cs
@@ -0,0 +1,17 @@
+using Umbraco.Cms.Core.Compose;
+using Umbraco.Cms.Core.Composing;
+using Umbraco.Cms.Core.DependencyInjection;
+using Umbraco.Cms.Infrastructure.Services.Notifications;
+
+namespace Umbraco.Cms.Infrastructure.PublishedCache.Compose
+{
+ public sealed class NotificationsComposer : ComponentComposer, ICoreComposer
+ {
+ public override void Compose(IUmbracoBuilder builder)
+ {
+ base.Compose(builder);
+
+ builder.AddNotificationHandler();
+ }
+ }
+}
diff --git a/src/Umbraco.PublishedCache.NuCache/PublishedSnapshotServiceEventHandler.cs b/src/Umbraco.PublishedCache.NuCache/PublishedSnapshotServiceEventHandler.cs
index 25ceb9fb6a..df02320d87 100644
--- a/src/Umbraco.PublishedCache.NuCache/PublishedSnapshotServiceEventHandler.cs
+++ b/src/Umbraco.PublishedCache.NuCache/PublishedSnapshotServiceEventHandler.cs
@@ -9,6 +9,7 @@ using Umbraco.Cms.Core.Services.Changes;
using Umbraco.Cms.Core.Services.Implement;
using Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement;
using Umbraco.Cms.Infrastructure.PublishedCache.Persistence;
+using Umbraco.Cms.Infrastructure.Services.Notifications;
using Umbraco.Extensions;
namespace Umbraco.Cms.Infrastructure.PublishedCache
@@ -16,7 +17,7 @@ namespace Umbraco.Cms.Infrastructure.PublishedCache
///
/// Subscribes to Umbraco events to ensure nucache remains consistent with the source data
///
- public class PublishedSnapshotServiceEventHandler : IDisposable
+ public class PublishedSnapshotServiceEventHandler : IDisposable, INotificationHandler
{
private readonly IRuntimeState _runtime;
private bool _disposedValue;
@@ -79,9 +80,6 @@ namespace Umbraco.Cms.Infrastructure.PublishedCache
ContentTypeService.ScopedRefreshedEntity += OnContentTypeRefreshedEntity;
MediaTypeService.ScopedRefreshedEntity += OnMediaTypeRefreshedEntity;
MemberTypeService.ScopedRefreshedEntity += OnMemberTypeRefreshedEntity;
-
- // TODO: This should be a cache refresher call!
- LocalizationService.SavedLanguage += OnLanguageSaved;
}
private void TearDownRepositoryEvents()
@@ -95,7 +93,6 @@ namespace Umbraco.Cms.Infrastructure.PublishedCache
ContentTypeService.ScopedRefreshedEntity -= OnContentTypeRefreshedEntity;
MediaTypeService.ScopedRefreshedEntity -= OnMediaTypeRefreshedEntity;
MemberTypeService.ScopedRefreshedEntity -= OnMemberTypeRefreshedEntity;
- LocalizationService.SavedLanguage -= OnLanguageSaved; // TODO: Shouldn't this be a cache refresher event?
}
// note: if the service is not ready, ie _isReady is false, then we still handle repository events,
@@ -156,13 +153,14 @@ namespace Umbraco.Cms.Infrastructure.PublishedCache
}
}
+ // TODO: This should be a cache refresher call!
///
/// If a is ever saved with a different culture, we need to rebuild all of the content nucache database table
///
- private void OnLanguageSaved(ILocalizationService sender, SaveEventArgs e)
+ public void Handle(LanguageSavedNotification notification)
{
// culture changed on an existing language
- var cultureChanged = e.SavedEntities.Any(x => !x.WasPropertyDirty(nameof(ILanguage.Id)) && x.WasPropertyDirty(nameof(ILanguage.IsoCode)));
+ var cultureChanged = notification.SavedEntities.Any(x => !x.WasPropertyDirty(nameof(ILanguage.Id)) && x.WasPropertyDirty(nameof(ILanguage.IsoCode)));
if (cultureChanged)
{
// Rebuild all content for all content types
diff --git a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/ScopedRepositoryTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/ScopedRepositoryTests.cs
index 96ba30905b..fcfd81a39d 100644
--- a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/ScopedRepositoryTests.cs
+++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/ScopedRepositoryTests.cs
@@ -6,6 +6,7 @@ using System.Linq;
using Microsoft.Extensions.Logging;
using NUnit.Framework;
using Umbraco.Cms.Core.Cache;
+using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Membership;
@@ -14,9 +15,12 @@ using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.Implement;
using Umbraco.Cms.Core.Sync;
using Umbraco.Cms.Core.Web;
+using Umbraco.Cms.Infrastructure.PublishedCache;
+using Umbraco.Cms.Infrastructure.Services.Notifications;
using Umbraco.Cms.Infrastructure.Sync;
using Umbraco.Cms.Tests.Common.Testing;
using Umbraco.Cms.Tests.Integration.Testing;
+using Umbraco.Extensions;
namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Scoping
{
@@ -44,6 +48,17 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Scoping
return result;
}
+ protected override void CustomTestSetup(IUmbracoBuilder builder)
+ {
+ builder.Services.AddUnique();
+ builder
+ .AddNotificationHandler()
+ .AddNotificationHandler()
+ .AddNotificationHandler()
+ .AddNotificationHandler();
+ builder.AddNotificationHandler();
+ }
+
[TearDown]
public void Teardown()
{
@@ -154,9 +169,6 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Scoping
Assert.AreEqual(lang.Id, globalCached.Id);
Assert.AreEqual("fr-FR", globalCached.IsoCode);
- _distributedCacheBinder = new DistributedCacheBinder(new DistributedCache(ServerMessenger, CacheRefresherCollection), GetRequiredService(), GetRequiredService>());
- _distributedCacheBinder.BindEvents(true);
-
Assert.IsNull(scopeProvider.AmbientScope);
using (IScope scope = scopeProvider.CreateScope(repositoryCacheMode: RepositoryCacheMode.Scoped))
{
@@ -250,8 +262,8 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Scoping
Assert.AreEqual(item.Id, globalCached.Id);
Assert.AreEqual("item-key", globalCached.ItemKey);
- _distributedCacheBinder = new DistributedCacheBinder(new DistributedCache(ServerMessenger, CacheRefresherCollection), GetRequiredService(), GetRequiredService>());
- _distributedCacheBinder.BindEvents(true);
+ // _distributedCacheBinder = new DistributedCacheBinder(new DistributedCache(ServerMessenger, CacheRefresherCollection), GetRequiredService(), GetRequiredService>());
+ // _distributedCacheBinder.BindEvents(true);
Assert.IsNull(scopeProvider.AmbientScope);
using (IScope scope = scopeProvider.CreateScope(repositoryCacheMode: RepositoryCacheMode.Scoped))