diff --git a/src/Umbraco.Core/Cache/ApplicationCacheRefresher.cs b/src/Umbraco.Core/Cache/ApplicationCacheRefresher.cs index 360fd44ba8..b8dccd1f59 100644 --- a/src/Umbraco.Core/Cache/ApplicationCacheRefresher.cs +++ b/src/Umbraco.Core/Cache/ApplicationCacheRefresher.cs @@ -1,17 +1,16 @@ using System; +using Umbraco.Cms.Core.Events; namespace Umbraco.Cms.Core.Cache { - public sealed class ApplicationCacheRefresher : CacheRefresherBase + public sealed class ApplicationCacheRefresher : CacheRefresherBase { - public ApplicationCacheRefresher(AppCaches appCaches) - : base(appCaches) + public ApplicationCacheRefresher(AppCaches appCaches, IEventAggregator eventAggregator) + : base(appCaches, eventAggregator) { } #region Define - protected override ApplicationCacheRefresher This => this; - public static readonly Guid UniqueId = Guid.Parse("B15F34A1-BC1D-4F8B-8369-3222728AB4C8"); public override Guid RefresherUniqueId => UniqueId; diff --git a/src/Umbraco.Core/Cache/CacheRefresherBase.cs b/src/Umbraco.Core/Cache/CacheRefresherBase.cs index d3a09dbf8f..be4129f928 100644 --- a/src/Umbraco.Core/Cache/CacheRefresherBase.cs +++ b/src/Umbraco.Core/Cache/CacheRefresherBase.cs @@ -10,33 +10,21 @@ namespace Umbraco.Cms.Core.Cache /// /// The actual cache refresher type. /// The actual cache refresher type is used for strongly typed events. - public abstract class CacheRefresherBase : ICacheRefresher - where TInstanceType : class, ICacheRefresher + public abstract class CacheRefresherBase< TNotification> : ICacheRefresher + where TNotification : CacheRefresherNotificationBase, new() { /// /// Initializes a new instance of the . /// /// A cache helper. - protected CacheRefresherBase(AppCaches appCaches) + protected CacheRefresherBase(AppCaches appCaches, IEventAggregator eventAggregator) { AppCaches = appCaches; + EventAggregator = eventAggregator; } - /// - /// Triggers when the cache is updated on the server. - /// - /// - /// Triggers on each server configured for an Umbraco project whenever a cache refresher is updated. - /// - public static event TypedEventHandler CacheUpdated; - #region Define - /// - /// Gets the typed 'this' for events. - /// - protected abstract TInstanceType This { get; } - /// /// Gets the unique identifier of the refresher. /// @@ -56,7 +44,7 @@ namespace Umbraco.Cms.Core.Cache /// public virtual void RefreshAll() { - OnCacheUpdated(This, new CacheRefresherEventArgs(null, MessageType.RefreshAll)); + OnCacheUpdated(new TNotification().Init(null, MessageType.RefreshAll)); } /// @@ -65,7 +53,7 @@ namespace Umbraco.Cms.Core.Cache /// The entity's identifier. public virtual void Refresh(int id) { - OnCacheUpdated(This, new CacheRefresherEventArgs(id, MessageType.RefreshById)); + OnCacheUpdated(new TNotification().Init(id, MessageType.RefreshById)); } /// @@ -74,7 +62,7 @@ namespace Umbraco.Cms.Core.Cache /// The entity's identifier. public virtual void Refresh(Guid id) { - OnCacheUpdated(This, new CacheRefresherEventArgs(id, MessageType.RefreshById)); + OnCacheUpdated(new TNotification().Init(id, MessageType.RefreshById)); } /// @@ -83,7 +71,7 @@ namespace Umbraco.Cms.Core.Cache /// The entity's identifier. public virtual void Remove(int id) { - OnCacheUpdated(This, new CacheRefresherEventArgs(id, MessageType.RemoveById)); + OnCacheUpdated(new TNotification().Init(id, MessageType.RemoveById)); } #endregion @@ -95,6 +83,8 @@ namespace Umbraco.Cms.Core.Cache /// protected AppCaches AppCaches { get; } + protected IEventAggregator EventAggregator { get; } + /// /// Clears the cache for all repository entities of a specified type. /// @@ -110,9 +100,9 @@ namespace Umbraco.Cms.Core.Cache /// /// The event sender. /// The event arguments. - protected static void OnCacheUpdated(TInstanceType sender, CacheRefresherEventArgs args) + protected void OnCacheUpdated(CacheRefresherNotificationBase notification) { - CacheUpdated?.Invoke(sender, args); + EventAggregator.Publish(notification); } #endregion diff --git a/src/Umbraco.Core/Cache/CacheRefresherEventArgs.cs b/src/Umbraco.Core/Cache/CacheRefresherEventArgs.cs deleted file mode 100644 index e1d04a7095..0000000000 --- a/src/Umbraco.Core/Cache/CacheRefresherEventArgs.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using Umbraco.Cms.Core.Sync; - -namespace Umbraco.Cms.Core.Cache -{ - /// - /// Event args for cache refresher updates - /// - public class CacheRefresherEventArgs : EventArgs - { - public CacheRefresherEventArgs(object msgObject, MessageType type) - { - MessageType = type; - MessageObject = msgObject; - } - public object MessageObject { get; private set; } - public MessageType MessageType { get; private set; } - } -} diff --git a/src/Umbraco.Core/Cache/CacheRefresherNotificationBase.cs b/src/Umbraco.Core/Cache/CacheRefresherNotificationBase.cs new file mode 100644 index 0000000000..7818678cfe --- /dev/null +++ b/src/Umbraco.Core/Cache/CacheRefresherNotificationBase.cs @@ -0,0 +1,83 @@ +using Umbraco.Cms.Core.Events; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Cache +{ + /// + /// Event args for cache refresher updates + /// + public abstract class CacheRefresherNotificationBase : INotification + { + public CacheRefresherNotificationBase Init(object msgObject, MessageType type) + { + MessageType = type; + MessageObject = msgObject; + + return this; + } + public object MessageObject { get; private set; } + public MessageType MessageType { get; private set;} + } + public class DataTypeCacheRefresherNotification : CacheRefresherNotificationBase + { + } + + public class UserCacheRefresherNotification : CacheRefresherNotificationBase + { + } + + + public class ContentCacheRefresherNotification : CacheRefresherNotificationBase + { + } + + public class TemplateCacheRefresherNotification : CacheRefresherNotificationBase + { + } + + public class RelationTypeCacheRefresherNotification : CacheRefresherNotificationBase + { + } + + public class PublicAccessCacheRefresherNotification : CacheRefresherNotificationBase + { + } + + public class MemberGroupCacheRefresherNotification : CacheRefresherNotificationBase + { + } + + public class MemberCacheRefresherNotification : CacheRefresherNotificationBase + { + } + + public class MediaCacheRefresherNotification : CacheRefresherNotificationBase + { + } + + public class UserGroupCacheRefresherNotification : CacheRefresherNotificationBase + { + } + + public class LanguageCacheRefresherNotification : CacheRefresherNotificationBase + { + } + public class MacroCacheRefresherNotification : CacheRefresherNotificationBase + { + } + + public class DomainCacheRefresherNotification : CacheRefresherNotificationBase + { + } + + public class ContentTypeCacheRefresherNotification : CacheRefresherNotificationBase + { + } + + public class ApplicationCacheRefresherNotification : CacheRefresherNotificationBase + { + } + public class DictionaryCacheRefresherNotification : CacheRefresherNotificationBase + { + } +} diff --git a/src/Umbraco.Core/Cache/ContentCacheRefresher.cs b/src/Umbraco.Core/Cache/ContentCacheRefresher.cs index e77fa7abef..42674d689b 100644 --- a/src/Umbraco.Core/Cache/ContentCacheRefresher.cs +++ b/src/Umbraco.Core/Cache/ContentCacheRefresher.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Persistence.Repositories; using Umbraco.Cms.Core.PublishedCache; @@ -11,14 +12,20 @@ using Umbraco.Extensions; namespace Umbraco.Cms.Core.Cache { - public sealed class ContentCacheRefresher : PayloadCacheRefresherBase + public sealed class ContentCacheRefresher : PayloadCacheRefresherBase { private readonly IPublishedSnapshotService _publishedSnapshotService; private readonly IIdKeyMap _idKeyMap; private readonly IDomainService _domainService; - public ContentCacheRefresher(AppCaches appCaches, IJsonSerializer serializer, IPublishedSnapshotService publishedSnapshotService, IIdKeyMap idKeyMap, IDomainService domainService) - : base(appCaches, serializer) + public ContentCacheRefresher( + AppCaches appCaches, + IJsonSerializer serializer, + IPublishedSnapshotService publishedSnapshotService, + IIdKeyMap idKeyMap, + IDomainService domainService, + IEventAggregator eventAggregator) + : base(appCaches, serializer, eventAggregator) { _publishedSnapshotService = publishedSnapshotService; _idKeyMap = idKeyMap; @@ -27,8 +34,6 @@ namespace Umbraco.Cms.Core.Cache #region Define - protected override ContentCacheRefresher This => this; - public static readonly Guid UniqueId = Guid.Parse("900A4FBE-DF3C-41E6-BB77-BE896CD158EA"); public override Guid RefresherUniqueId => UniqueId; diff --git a/src/Umbraco.Core/Cache/ContentTypeCacheRefresher.cs b/src/Umbraco.Core/Cache/ContentTypeCacheRefresher.cs index 8a1ba1234e..00838865ce 100644 --- a/src/Umbraco.Core/Cache/ContentTypeCacheRefresher.cs +++ b/src/Umbraco.Core/Cache/ContentTypeCacheRefresher.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.PublishedContent; using Umbraco.Cms.Core.Persistence.Repositories; @@ -11,15 +12,22 @@ using Umbraco.Extensions; namespace Umbraco.Cms.Core.Cache { - public sealed class ContentTypeCacheRefresher : PayloadCacheRefresherBase + public sealed class ContentTypeCacheRefresher : PayloadCacheRefresherBase { private readonly IPublishedSnapshotService _publishedSnapshotService; private readonly IPublishedModelFactory _publishedModelFactory; private readonly IContentTypeCommonRepository _contentTypeCommonRepository; private readonly IIdKeyMap _idKeyMap; - public ContentTypeCacheRefresher(AppCaches appCaches, IJsonSerializer serializer, IPublishedSnapshotService publishedSnapshotService, IPublishedModelFactory publishedModelFactory, IIdKeyMap idKeyMap, IContentTypeCommonRepository contentTypeCommonRepository) - : base(appCaches, serializer) + public ContentTypeCacheRefresher( + AppCaches appCaches, + IJsonSerializer serializer, + IPublishedSnapshotService publishedSnapshotService, + IPublishedModelFactory publishedModelFactory, + IIdKeyMap idKeyMap, + IContentTypeCommonRepository contentTypeCommonRepository, + IEventAggregator eventAggregator) + : base(appCaches, serializer, eventAggregator) { _publishedSnapshotService = publishedSnapshotService; _publishedModelFactory = publishedModelFactory; @@ -29,8 +37,6 @@ namespace Umbraco.Cms.Core.Cache #region Define - protected override ContentTypeCacheRefresher This => this; - public static readonly Guid UniqueId = Guid.Parse("6902E22C-9C10-483C-91F3-66B7CAE9E2F5"); public override Guid RefresherUniqueId => UniqueId; diff --git a/src/Umbraco.Core/Cache/DataTypeCacheRefresher.cs b/src/Umbraco.Core/Cache/DataTypeCacheRefresher.cs index d5e11e17d3..0eca1a0c20 100644 --- a/src/Umbraco.Core/Cache/DataTypeCacheRefresher.cs +++ b/src/Umbraco.Core/Cache/DataTypeCacheRefresher.cs @@ -1,4 +1,5 @@ using System; +using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.PublishedContent; using Umbraco.Cms.Core.PropertyEditors.ValueConverters; @@ -9,14 +10,20 @@ using Umbraco.Extensions; namespace Umbraco.Cms.Core.Cache { - public sealed class DataTypeCacheRefresher : PayloadCacheRefresherBase + public sealed class DataTypeCacheRefresher : PayloadCacheRefresherBase { private readonly IPublishedSnapshotService _publishedSnapshotService; private readonly IPublishedModelFactory _publishedModelFactory; private readonly IIdKeyMap _idKeyMap; - public DataTypeCacheRefresher(AppCaches appCaches, IJsonSerializer serializer, IPublishedSnapshotService publishedSnapshotService, IPublishedModelFactory publishedModelFactory, IIdKeyMap idKeyMap) - : base(appCaches, serializer) + public DataTypeCacheRefresher( + AppCaches appCaches, + IJsonSerializer serializer, + IPublishedSnapshotService publishedSnapshotService, + IPublishedModelFactory publishedModelFactory, + IIdKeyMap idKeyMap, + IEventAggregator eventAggregator) + : base(appCaches, serializer, eventAggregator) { _publishedSnapshotService = publishedSnapshotService; _publishedModelFactory = publishedModelFactory; @@ -25,8 +32,6 @@ namespace Umbraco.Cms.Core.Cache #region Define - protected override DataTypeCacheRefresher This => this; - public static readonly Guid UniqueId = Guid.Parse("35B16C25-A17E-45D7-BC8F-EDAB1DCC28D2"); public override Guid RefresherUniqueId => UniqueId; diff --git a/src/Umbraco.Core/Cache/DictionaryCacheRefresher.cs b/src/Umbraco.Core/Cache/DictionaryCacheRefresher.cs index 922afab8da..8e21146a96 100644 --- a/src/Umbraco.Core/Cache/DictionaryCacheRefresher.cs +++ b/src/Umbraco.Core/Cache/DictionaryCacheRefresher.cs @@ -1,18 +1,17 @@ using System; +using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Models; namespace Umbraco.Cms.Core.Cache { - public sealed class DictionaryCacheRefresher : CacheRefresherBase + public sealed class DictionaryCacheRefresher : CacheRefresherBase { - public DictionaryCacheRefresher(AppCaches appCaches) - : base(appCaches) + public DictionaryCacheRefresher(AppCaches appCaches, IEventAggregator eventAggregator) + : base(appCaches, eventAggregator) { } #region Define - protected override DictionaryCacheRefresher This => this; - public static readonly Guid UniqueId = Guid.Parse("D1D7E227-F817-4816-BFE9-6C39B6152884"); public override Guid RefresherUniqueId => UniqueId; diff --git a/src/Umbraco.Core/Cache/DomainCacheRefresher.cs b/src/Umbraco.Core/Cache/DomainCacheRefresher.cs index 2773ca2d0f..098b200632 100644 --- a/src/Umbraco.Core/Cache/DomainCacheRefresher.cs +++ b/src/Umbraco.Core/Cache/DomainCacheRefresher.cs @@ -1,4 +1,5 @@ using System; +using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.PublishedCache; using Umbraco.Cms.Core.Serialization; @@ -6,20 +7,22 @@ using Umbraco.Cms.Core.Services.Changes; namespace Umbraco.Cms.Core.Cache { - public sealed class DomainCacheRefresher : PayloadCacheRefresherBase + public sealed class DomainCacheRefresher : PayloadCacheRefresherBase { private readonly IPublishedSnapshotService _publishedSnapshotService; - public DomainCacheRefresher(AppCaches appCaches, IJsonSerializer serializer, IPublishedSnapshotService publishedSnapshotService) - : base(appCaches, serializer) + public DomainCacheRefresher( + AppCaches appCaches, + IJsonSerializer serializer, + IPublishedSnapshotService publishedSnapshotService, + IEventAggregator eventAggregator) + : base(appCaches, serializer, eventAggregator) { _publishedSnapshotService = publishedSnapshotService; } #region Define - protected override DomainCacheRefresher This => this; - public static readonly Guid UniqueId = Guid.Parse("11290A79-4B57-4C99-AD72-7748A3CF38AF"); public override Guid RefresherUniqueId => UniqueId; diff --git a/src/Umbraco.Core/Cache/JsonCacheRefresherBase.cs b/src/Umbraco.Core/Cache/JsonCacheRefresherBase.cs index 3e70bc54eb..4ad5842373 100644 --- a/src/Umbraco.Core/Cache/JsonCacheRefresherBase.cs +++ b/src/Umbraco.Core/Cache/JsonCacheRefresherBase.cs @@ -1,4 +1,5 @@ -using Umbraco.Cms.Core.Serialization; +using Umbraco.Cms.Core.Events; +using Umbraco.Cms.Core.Serialization; using Umbraco.Cms.Core.Sync; namespace Umbraco.Cms.Core.Cache @@ -8,8 +9,8 @@ namespace Umbraco.Cms.Core.Cache /// /// The actual cache refresher type. /// The actual cache refresher type is used for strongly typed events. - public abstract class JsonCacheRefresherBase : CacheRefresherBase, IJsonCacheRefresher - where TInstanceType : class, ICacheRefresher + public abstract class JsonCacheRefresherBase : CacheRefresherBase, IJsonCacheRefresher + where TNotification : CacheRefresherNotificationBase, new() { protected IJsonSerializer JsonSerializer { get; } @@ -17,7 +18,11 @@ namespace Umbraco.Cms.Core.Cache /// Initializes a new instance of the . /// /// A cache helper. - protected JsonCacheRefresherBase(AppCaches appCaches, IJsonSerializer jsonSerializer) : base(appCaches) + protected JsonCacheRefresherBase( + AppCaches appCaches, + IJsonSerializer jsonSerializer, + IEventAggregator eventAggregator) + : base(appCaches, eventAggregator) { JsonSerializer = jsonSerializer; } @@ -28,7 +33,7 @@ namespace Umbraco.Cms.Core.Cache /// The json payload. public virtual void Refresh(string json) { - OnCacheUpdated(This, new CacheRefresherEventArgs(json, MessageType.RefreshByJson)); + OnCacheUpdated(new TNotification().Init(json, MessageType.RefreshByJson)); } #region Json diff --git a/src/Umbraco.Core/Cache/LanguageCacheRefresher.cs b/src/Umbraco.Core/Cache/LanguageCacheRefresher.cs index b15d247ddf..1e9ff228df 100644 --- a/src/Umbraco.Core/Cache/LanguageCacheRefresher.cs +++ b/src/Umbraco.Core/Cache/LanguageCacheRefresher.cs @@ -1,4 +1,5 @@ using System; +using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.PublishedCache; using Umbraco.Cms.Core.Serialization; @@ -7,18 +8,20 @@ using static Umbraco.Cms.Core.Cache.LanguageCacheRefresher.JsonPayload; namespace Umbraco.Cms.Core.Cache { - public sealed class LanguageCacheRefresher : PayloadCacheRefresherBase + public sealed class LanguageCacheRefresher : PayloadCacheRefresherBase { - public LanguageCacheRefresher(AppCaches appCaches, IJsonSerializer serializer, IPublishedSnapshotService publishedSnapshotService) - : base(appCaches, serializer) + public LanguageCacheRefresher( + AppCaches appCaches, + IJsonSerializer serializer, + IPublishedSnapshotService publishedSnapshotService, + IEventAggregator eventAggregator) + : base(appCaches, serializer, eventAggregator) { _publishedSnapshotService = publishedSnapshotService; } #region Define - protected override LanguageCacheRefresher This => this; - public static readonly Guid UniqueId = Guid.Parse("3E0F95D8-0BE5-44B8-8394-2B8750B62654"); private readonly IPublishedSnapshotService _publishedSnapshotService; diff --git a/src/Umbraco.Core/Cache/MacroCacheRefresher.cs b/src/Umbraco.Core/Cache/MacroCacheRefresher.cs index dd4c4c73de..5e6c3294ab 100644 --- a/src/Umbraco.Core/Cache/MacroCacheRefresher.cs +++ b/src/Umbraco.Core/Cache/MacroCacheRefresher.cs @@ -1,23 +1,25 @@ using System; using System.Linq; +using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Persistence.Repositories; using Umbraco.Cms.Core.Serialization; namespace Umbraco.Cms.Core.Cache { - public sealed class MacroCacheRefresher : PayloadCacheRefresherBase + public sealed class MacroCacheRefresher : PayloadCacheRefresherBase { - public MacroCacheRefresher(AppCaches appCaches, IJsonSerializer jsonSerializer) - : base(appCaches, jsonSerializer) + public MacroCacheRefresher( + AppCaches appCaches, + IJsonSerializer jsonSerializer, + IEventAggregator eventAggregator) + : base(appCaches, jsonSerializer, eventAggregator) { } #region Define - protected override MacroCacheRefresher This => this; - public static readonly Guid UniqueId = Guid.Parse("7B1E683C-5F34-43dd-803D-9699EA1E98CA"); public override Guid RefresherUniqueId => UniqueId; diff --git a/src/Umbraco.Core/Cache/MediaCacheRefresher.cs b/src/Umbraco.Core/Cache/MediaCacheRefresher.cs index 997083b0a7..a4f424acf2 100644 --- a/src/Umbraco.Core/Cache/MediaCacheRefresher.cs +++ b/src/Umbraco.Core/Cache/MediaCacheRefresher.cs @@ -1,4 +1,5 @@ using System; +using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Persistence.Repositories; using Umbraco.Cms.Core.PublishedCache; @@ -9,13 +10,13 @@ using Umbraco.Extensions; namespace Umbraco.Cms.Core.Cache { - public sealed class MediaCacheRefresher : PayloadCacheRefresherBase + public sealed class MediaCacheRefresher : PayloadCacheRefresherBase { private readonly IPublishedSnapshotService _publishedSnapshotService; private readonly IIdKeyMap _idKeyMap; - public MediaCacheRefresher(AppCaches appCaches, IJsonSerializer serializer, IPublishedSnapshotService publishedSnapshotService, IIdKeyMap idKeyMap) - : base(appCaches, serializer) + public MediaCacheRefresher(AppCaches appCaches, IJsonSerializer serializer, IPublishedSnapshotService publishedSnapshotService, IIdKeyMap idKeyMap, IEventAggregator eventAggregator) + : base(appCaches, serializer, eventAggregator) { _publishedSnapshotService = publishedSnapshotService; _idKeyMap = idKeyMap; @@ -23,8 +24,6 @@ namespace Umbraco.Cms.Core.Cache #region Define - protected override MediaCacheRefresher This => this; - public static readonly Guid UniqueId = Guid.Parse("B29286DD-2D40-4DDB-B325-681226589FEC"); public override Guid RefresherUniqueId => UniqueId; diff --git a/src/Umbraco.Core/Cache/MemberCacheRefresher.cs b/src/Umbraco.Core/Cache/MemberCacheRefresher.cs index 0932725fe4..40f324384b 100644 --- a/src/Umbraco.Core/Cache/MemberCacheRefresher.cs +++ b/src/Umbraco.Core/Cache/MemberCacheRefresher.cs @@ -1,6 +1,7 @@ //using Newtonsoft.Json; using System; +using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Persistence.Repositories; using Umbraco.Cms.Core.Serialization; @@ -9,12 +10,12 @@ using Umbraco.Extensions; namespace Umbraco.Cms.Core.Cache { - public sealed class MemberCacheRefresher : PayloadCacheRefresherBase + public sealed class MemberCacheRefresher : PayloadCacheRefresherBase { private readonly IIdKeyMap _idKeyMap; - public MemberCacheRefresher(AppCaches appCaches, IJsonSerializer serializer, IIdKeyMap idKeyMap) - : base(appCaches, serializer) + public MemberCacheRefresher(AppCaches appCaches, IJsonSerializer serializer, IIdKeyMap idKeyMap, IEventAggregator eventAggregator) + : base(appCaches, serializer, eventAggregator) { _idKeyMap = idKeyMap; } @@ -36,8 +37,6 @@ namespace Umbraco.Cms.Core.Cache #region Define - protected override MemberCacheRefresher This => this; - public static readonly Guid UniqueId = Guid.Parse("E285DF34-ACDC-4226-AE32-C0CB5CF388DA"); public override Guid RefresherUniqueId => UniqueId; diff --git a/src/Umbraco.Core/Cache/MemberGroupCacheRefresher.cs b/src/Umbraco.Core/Cache/MemberGroupCacheRefresher.cs index 2db947d026..637d4c8558 100644 --- a/src/Umbraco.Core/Cache/MemberGroupCacheRefresher.cs +++ b/src/Umbraco.Core/Cache/MemberGroupCacheRefresher.cs @@ -1,21 +1,20 @@ using System; +using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Serialization; namespace Umbraco.Cms.Core.Cache { - public sealed class MemberGroupCacheRefresher : PayloadCacheRefresherBase + public sealed class MemberGroupCacheRefresher : PayloadCacheRefresherBase { - public MemberGroupCacheRefresher(AppCaches appCaches, IJsonSerializer jsonSerializer) - : base(appCaches, jsonSerializer) + public MemberGroupCacheRefresher(AppCaches appCaches, IJsonSerializer jsonSerializer, IEventAggregator eventAggregator) + : base(appCaches, jsonSerializer, eventAggregator) { } #region Define - protected override MemberGroupCacheRefresher This => this; - public static readonly Guid UniqueId = Guid.Parse("187F236B-BD21-4C85-8A7C-29FBA3D6C00C"); public override Guid RefresherUniqueId => UniqueId; diff --git a/src/Umbraco.Core/Cache/PayloadCacheRefresherBase.cs b/src/Umbraco.Core/Cache/PayloadCacheRefresherBase.cs index 08d3e65506..dd11e899c0 100644 --- a/src/Umbraco.Core/Cache/PayloadCacheRefresherBase.cs +++ b/src/Umbraco.Core/Cache/PayloadCacheRefresherBase.cs @@ -1,4 +1,5 @@ -using Umbraco.Cms.Core.Serialization; +using Umbraco.Cms.Core.Events; +using Umbraco.Cms.Core.Serialization; using Umbraco.Cms.Core.Sync; namespace Umbraco.Cms.Core.Cache @@ -9,8 +10,9 @@ namespace Umbraco.Cms.Core.Cache /// The actual cache refresher type. /// The payload type. /// The actual cache refresher type is used for strongly typed events. - public abstract class PayloadCacheRefresherBase : JsonCacheRefresherBase, IPayloadCacheRefresher - where TInstanceType : class, ICacheRefresher + public abstract class PayloadCacheRefresherBase : JsonCacheRefresherBase, IPayloadCacheRefresher + where TNotification : CacheRefresherNotificationBase, new() + { /// @@ -18,7 +20,8 @@ namespace Umbraco.Cms.Core.Cache /// /// A cache helper. /// - protected PayloadCacheRefresherBase(AppCaches appCaches, IJsonSerializer serializer) : base(appCaches, serializer) + protected PayloadCacheRefresherBase(AppCaches appCaches, IJsonSerializer serializer, IEventAggregator eventAggregator) + : base(appCaches, serializer, eventAggregator) { } @@ -37,7 +40,7 @@ namespace Umbraco.Cms.Core.Cache /// The payload. public virtual void Refresh(TPayload[] payloads) { - OnCacheUpdated(This, new CacheRefresherEventArgs(payloads, MessageType.RefreshByPayload)); + OnCacheUpdated(new TNotification().Init(payloads, MessageType.RefreshByPayload)); } #endregion diff --git a/src/Umbraco.Core/Cache/PublicAccessCacheRefresher.cs b/src/Umbraco.Core/Cache/PublicAccessCacheRefresher.cs index 19064a8031..44b108fa23 100644 --- a/src/Umbraco.Core/Cache/PublicAccessCacheRefresher.cs +++ b/src/Umbraco.Core/Cache/PublicAccessCacheRefresher.cs @@ -1,18 +1,17 @@ using System; +using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Models; namespace Umbraco.Cms.Core.Cache { - public sealed class PublicAccessCacheRefresher : CacheRefresherBase + public sealed class PublicAccessCacheRefresher : CacheRefresherBase { - public PublicAccessCacheRefresher(AppCaches appCaches) - : base(appCaches) + public PublicAccessCacheRefresher(AppCaches appCaches, IEventAggregator eventAggregator) + : base(appCaches, eventAggregator) { } #region Define - protected override PublicAccessCacheRefresher This => this; - public static readonly Guid UniqueId = Guid.Parse("1DB08769-B104-4F8B-850E-169CAC1DF2EC"); public override Guid RefresherUniqueId => UniqueId; diff --git a/src/Umbraco.Core/Cache/RelationTypeCacheRefresher.cs b/src/Umbraco.Core/Cache/RelationTypeCacheRefresher.cs index daa954b257..d82cef759d 100644 --- a/src/Umbraco.Core/Cache/RelationTypeCacheRefresher.cs +++ b/src/Umbraco.Core/Cache/RelationTypeCacheRefresher.cs @@ -1,19 +1,18 @@ using System; +using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Persistence.Repositories; namespace Umbraco.Cms.Core.Cache { - public sealed class RelationTypeCacheRefresher : CacheRefresherBase + public sealed class RelationTypeCacheRefresher : CacheRefresherBase { - public RelationTypeCacheRefresher(AppCaches appCaches) - : base(appCaches) + public RelationTypeCacheRefresher(AppCaches appCaches, IEventAggregator eventAggregator) + : base(appCaches, eventAggregator) { } #region Define - protected override RelationTypeCacheRefresher This => this; - public static readonly Guid UniqueId = Guid.Parse("D8375ABA-4FB3-4F86-B505-92FBA1B6F7C9"); public override Guid RefresherUniqueId => UniqueId; diff --git a/src/Umbraco.Core/Cache/TemplateCacheRefresher.cs b/src/Umbraco.Core/Cache/TemplateCacheRefresher.cs index d02d3190eb..6c33a44545 100644 --- a/src/Umbraco.Core/Cache/TemplateCacheRefresher.cs +++ b/src/Umbraco.Core/Cache/TemplateCacheRefresher.cs @@ -1,17 +1,18 @@ using System; +using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Persistence.Repositories; using Umbraco.Cms.Core.Services; namespace Umbraco.Cms.Core.Cache { - public sealed class TemplateCacheRefresher : CacheRefresherBase + public sealed class TemplateCacheRefresher : CacheRefresherBase { private readonly IIdKeyMap _idKeyMap; private readonly IContentTypeCommonRepository _contentTypeCommonRepository; - public TemplateCacheRefresher(AppCaches appCaches, IIdKeyMap idKeyMap, IContentTypeCommonRepository contentTypeCommonRepository) - : base(appCaches) + public TemplateCacheRefresher(AppCaches appCaches, IIdKeyMap idKeyMap, IContentTypeCommonRepository contentTypeCommonRepository, IEventAggregator eventAggregator) + : base(appCaches, eventAggregator) { _idKeyMap = idKeyMap; _contentTypeCommonRepository = contentTypeCommonRepository; @@ -19,8 +20,6 @@ namespace Umbraco.Cms.Core.Cache #region Define - protected override TemplateCacheRefresher This => this; - public static readonly Guid UniqueId = Guid.Parse("DD12B6A0-14B9-46e8-8800-C154F74047C8"); public override Guid RefresherUniqueId => UniqueId; diff --git a/src/Umbraco.Core/Cache/UserCacheRefresher.cs b/src/Umbraco.Core/Cache/UserCacheRefresher.cs index 6cb3eb7f88..b8fd75702e 100644 --- a/src/Umbraco.Core/Cache/UserCacheRefresher.cs +++ b/src/Umbraco.Core/Cache/UserCacheRefresher.cs @@ -1,19 +1,18 @@ using System; +using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Models.Membership; using Umbraco.Cms.Core.Persistence.Repositories; namespace Umbraco.Cms.Core.Cache { - public sealed class UserCacheRefresher : CacheRefresherBase + public sealed class UserCacheRefresher : CacheRefresherBase { - public UserCacheRefresher(AppCaches appCaches) - : base(appCaches) + public UserCacheRefresher(AppCaches appCaches, IEventAggregator eventAggregator) + : base(appCaches, eventAggregator) { } #region Define - protected override UserCacheRefresher This => this; - public static readonly Guid UniqueId = Guid.Parse("E057AF6D-2EE6-41F4-8045-3694010F0AA6"); public override Guid RefresherUniqueId => UniqueId; @@ -47,7 +46,7 @@ namespace Umbraco.Cms.Core.Cache userCache.Result.ClearByKey(CacheKeys.UserAllContentStartNodesPrefix + id); userCache.Result.ClearByKey(CacheKeys.UserAllMediaStartNodesPrefix + id); } - + base.Remove(id); } diff --git a/src/Umbraco.Core/Cache/UserGroupCacheRefresher.cs b/src/Umbraco.Core/Cache/UserGroupCacheRefresher.cs index 7519994069..f4456ef696 100644 --- a/src/Umbraco.Core/Cache/UserGroupCacheRefresher.cs +++ b/src/Umbraco.Core/Cache/UserGroupCacheRefresher.cs @@ -1,4 +1,5 @@ using System; +using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Models.Membership; using Umbraco.Cms.Core.Persistence.Repositories; @@ -10,16 +11,14 @@ namespace Umbraco.Cms.Core.Cache /// /// This also needs to clear the user cache since IReadOnlyUserGroup's are attached to IUser objects /// - public sealed class UserGroupCacheRefresher : CacheRefresherBase + public sealed class UserGroupCacheRefresher : CacheRefresherBase { - public UserGroupCacheRefresher(AppCaches appCaches) - : base(appCaches) + public UserGroupCacheRefresher(AppCaches appCaches, IEventAggregator eventAggregator) + : base(appCaches, eventAggregator) { } #region Define - protected override UserGroupCacheRefresher This => this; - public static readonly Guid UniqueId = Guid.Parse("45178038-B232-4FE8-AA1A-F2B949C44762"); public override Guid RefresherUniqueId => UniqueId; diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index ce524a09a1..0cbbee528e 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -51,4 +51,8 @@ + + + + diff --git a/src/Umbraco.Infrastructure/Search/ExamineComposer.cs b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Examine.cs similarity index 69% rename from src/Umbraco.Infrastructure/Search/ExamineComposer.cs rename to src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Examine.cs index 45ba3c461e..033ab76298 100644 --- a/src/Umbraco.Infrastructure/Search/ExamineComposer.cs +++ b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Examine.cs @@ -1,25 +1,25 @@ using Microsoft.Extensions.DependencyInjection; -using Umbraco.Cms.Core.Composing; +using Umbraco.Cms.Core.Cache; using Umbraco.Cms.Core.DependencyInjection; +using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.PropertyEditors; using Umbraco.Cms.Core.Scoping; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Strings; using Umbraco.Cms.Infrastructure.Examine; +using Umbraco.Cms.Infrastructure.Search; using Umbraco.Extensions; -namespace Umbraco.Cms.Infrastructure.Search +namespace Umbraco.Cms.Infrastructure.DependencyInjection { /// - /// Configures and installs Examine. + /// Provides extension methods to the class. /// - public sealed class ExamineComposer : ComponentComposer, ICoreComposer + public static partial class UmbracoBuilderExtensions { - public override void Compose(IUmbracoBuilder builder) + public static IUmbracoBuilder AddExamine(this IUmbracoBuilder builder) { - base.Compose(builder); - // populators are not a collection: one cannot remove ours, and can only add more // the container can inject IEnumerable and get them all builder.Services.AddSingleton(); @@ -49,6 +49,15 @@ namespace Umbraco.Cms.Infrastructure.Search builder.Services.AddUnique, MediaValueSetBuilder>(); builder.Services.AddUnique, MemberValueSetBuilder>(); builder.Services.AddUnique(); + + builder.AddNotificationHandler(); + builder.AddNotificationHandler(); + builder.AddNotificationHandler(); + builder.AddNotificationHandler(); + builder.AddNotificationHandler(); + builder.AddNotificationHandler(); + + return builder; } } } diff --git a/src/Umbraco.Infrastructure/ModelsBuilder/LiveModelsProvider.cs b/src/Umbraco.Infrastructure/ModelsBuilder/LiveModelsProvider.cs index 2c0a71016a..9ff03e4d45 100644 --- a/src/Umbraco.Infrastructure/ModelsBuilder/LiveModelsProvider.cs +++ b/src/Umbraco.Infrastructure/ModelsBuilder/LiveModelsProvider.cs @@ -12,7 +12,10 @@ using Umbraco.Extensions; namespace Umbraco.Cms.Infrastructure.ModelsBuilder { // supports LiveAppData - but not PureLive - public sealed class LiveModelsProvider : INotificationHandler, INotificationHandler + public sealed class LiveModelsProvider : INotificationHandler, + INotificationHandler, + INotificationHandler, + INotificationHandler { private static int s_req; private readonly ILogger _logger; @@ -53,16 +56,6 @@ namespace Umbraco.Cms.Infrastructure.ModelsBuilder { return; } - - // Must register with maindom in order to function. - // If registration is not successful then events are not bound - // and we also don't generate models. - _mainDom.Register(() => - { - // anything changes, and we want to re-generate models. - ContentTypeCacheRefresher.CacheUpdated += RequestModelsGeneration; - DataTypeCacheRefresher.CacheUpdated += RequestModelsGeneration; - }); } // NOTE @@ -72,8 +65,13 @@ namespace Umbraco.Cms.Infrastructure.ModelsBuilder // need to be generated. Could be by another request. Anyway. We could // have collisions but... you know the risk. - private void RequestModelsGeneration(object sender, EventArgs args) + private void RequestModelsGeneration() { + if (!_mainDom.IsMainDom) + { + return; + } + _logger.LogDebug("Requested to generate models."); Interlocked.Exchange(ref s_req, 1); } @@ -121,5 +119,9 @@ namespace Umbraco.Cms.Infrastructure.ModelsBuilder GenerateModelsIfRequested(); } } + + public void Handle(ContentTypeCacheRefresherNotification notification) => RequestModelsGeneration(); + + public void Handle(DataTypeCacheRefresherNotification notification) => RequestModelsGeneration(); } } diff --git a/src/Umbraco.Infrastructure/ModelsBuilder/OutOfDateModelsStatus.cs b/src/Umbraco.Infrastructure/ModelsBuilder/OutOfDateModelsStatus.cs index 65a7ac3ef8..8b14a6030b 100644 --- a/src/Umbraco.Infrastructure/ModelsBuilder/OutOfDateModelsStatus.cs +++ b/src/Umbraco.Infrastructure/ModelsBuilder/OutOfDateModelsStatus.cs @@ -11,7 +11,8 @@ namespace Umbraco.Cms.Infrastructure.ModelsBuilder /// /// Used to track if ModelsBuilder models are out of date/stale /// - public sealed class OutOfDateModelsStatus : INotificationHandler + public sealed class OutOfDateModelsStatus : INotificationHandler, + INotificationHandler { private readonly ModelsBuilderSettings _config; private readonly IHostingEnvironment _hostingEnvironment; @@ -47,22 +48,6 @@ namespace Umbraco.Cms.Infrastructure.ModelsBuilder } } - /// - /// Handles the notification - /// - public void Handle(UmbracoApplicationStarting notification) => Install(); - - private void Install() - { - // don't run if not configured - if (!IsEnabled) - { - return; - } - - ContentTypeCacheRefresher.CacheUpdated += (sender, args) => Write(); - DataTypeCacheRefresher.CacheUpdated += (sender, args) => Write(); - } private string GetFlagPath() { @@ -77,6 +62,12 @@ namespace Umbraco.Cms.Infrastructure.ModelsBuilder private void Write() { + // don't run if not configured + if (!IsEnabled) + { + return; + } + var path = GetFlagPath(); if (path == null || File.Exists(path)) { @@ -101,5 +92,9 @@ namespace Umbraco.Cms.Infrastructure.ModelsBuilder File.Delete(path); } + + public void Handle(ContentTypeCacheRefresherNotification notification) => Write(); + + public void Handle(DataTypeCacheRefresherNotification notification) => Write(); } } diff --git a/src/Umbraco.Infrastructure/Search/ExamineComponent.cs b/src/Umbraco.Infrastructure/Search/ExamineNotificationHandler.cs similarity index 86% rename from src/Umbraco.Infrastructure/Search/ExamineComponent.cs rename to src/Umbraco.Infrastructure/Search/ExamineNotificationHandler.cs index 30dc01dc9a..dd95b6931e 100644 --- a/src/Umbraco.Infrastructure/Search/ExamineComponent.cs +++ b/src/Umbraco.Infrastructure/Search/ExamineNotificationHandler.cs @@ -7,7 +7,7 @@ using Examine; using Microsoft.Extensions.Logging; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Cache; -using Umbraco.Cms.Core.Composing; +using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Logging; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Runtime; @@ -20,7 +20,13 @@ using Umbraco.Extensions; namespace Umbraco.Cms.Infrastructure.Search { - public sealed class ExamineComponent : IComponent + public sealed class ExamineNotificationHandler : + INotificationHandler, + INotificationHandler, + INotificationHandler, + INotificationHandler, + INotificationHandler, + INotificationHandler { private readonly IExamineManager _examineManager; private readonly IContentValueSetBuilder _contentValueSetBuilder; @@ -33,18 +39,19 @@ namespace Umbraco.Cms.Infrastructure.Search private readonly ServiceContext _services; private readonly IMainDom _mainDom; private readonly IProfilingLogger _profilingLogger; - private readonly ILogger _logger; + private readonly ILogger _logger; private readonly IUmbracoIndexesCreator _indexCreator; + private static bool s_deactivate_handlers; // the default enlist priority is 100 // enlist with a lower priority to ensure that anything "default" runs after us // but greater that SafeXmlReaderWriter priority which is 60 private const int EnlistPriority = 80; - public ExamineComponent(IMainDom mainDom, + public ExamineNotificationHandler(IMainDom mainDom, IExamineManager examineManager, IProfilingLogger profilingLogger, - ILoggerFactory loggerFactory, + ILogger logger, IScopeProvider scopeProvider, IUmbracoIndexesCreator indexCreator, ServiceContext services, @@ -66,16 +73,15 @@ namespace Umbraco.Cms.Infrastructure.Search _taskHelper = taskHelper; _mainDom = mainDom; _profilingLogger = profilingLogger; - _logger = loggerFactory.CreateLogger(); + _logger = logger; _indexCreator = indexCreator; } - - public void Initialize() + public void Handle(UmbracoApplicationStarting notification) { //let's deal with shutting down Examine with MainDom var examineShutdownRegistered = _mainDom.Register(release: () => { - using (_profilingLogger.TraceDuration("Examine shutting down")) + using (_profilingLogger.TraceDuration("Examine shutting down")) { _examineManager.Dispose(); } @@ -105,26 +111,12 @@ namespace Umbraco.Cms.Infrastructure.Search // don't bind event handlers if we're not suppose to listen if (registeredIndexers == 0) { - return; + s_deactivate_handlers = true; } - // bind to distributed cache events - this ensures that this logic occurs on ALL servers - // that are taking part in a load balanced environment. - ContentCacheRefresher.CacheUpdated += ContentCacheRefresherUpdated; - ContentTypeCacheRefresher.CacheUpdated += ContentTypeCacheRefresherUpdated; - MediaCacheRefresher.CacheUpdated += MediaCacheRefresherUpdated; - MemberCacheRefresher.CacheUpdated += MemberCacheRefresherUpdated; - LanguageCacheRefresher.CacheUpdated += LanguageCacheRefresherUpdated; + } - public void Terminate() - { - ContentCacheRefresher.CacheUpdated -= ContentCacheRefresherUpdated; - ContentTypeCacheRefresher.CacheUpdated -= ContentTypeCacheRefresherUpdated; - MediaCacheRefresher.CacheUpdated -= MediaCacheRefresherUpdated; - MemberCacheRefresher.CacheUpdated -= MemberCacheRefresherUpdated; - LanguageCacheRefresher.CacheUpdated -= LanguageCacheRefresherUpdated; - } #region Cache refresher updated event handlers @@ -133,8 +125,12 @@ namespace Umbraco.Cms.Infrastructure.Search /// /// /// - private void ContentCacheRefresherUpdated(ContentCacheRefresher sender, CacheRefresherEventArgs args) + public void Handle(ContentCacheRefresherNotification args) { + if (s_deactivate_handlers) + { + return;; + } if (Suspendable.ExamineEvents.CanIndex == false) { return; @@ -237,8 +233,13 @@ namespace Umbraco.Cms.Infrastructure.Search } } - private void MemberCacheRefresherUpdated(MemberCacheRefresher sender, CacheRefresherEventArgs args) + public void Handle(MemberCacheRefresherNotification args) { + if (s_deactivate_handlers) + { + return;; + } + if (Suspendable.ExamineEvents.CanIndex == false) { return; @@ -300,8 +301,13 @@ namespace Umbraco.Cms.Infrastructure.Search } } - private void MediaCacheRefresherUpdated(MediaCacheRefresher sender, CacheRefresherEventArgs args) + public void Handle(MediaCacheRefresherNotification args) { + if (s_deactivate_handlers) + { + return;; + } + if (Suspendable.ExamineEvents.CanIndex == false) { return; @@ -364,9 +370,14 @@ namespace Umbraco.Cms.Infrastructure.Search } } - private void LanguageCacheRefresherUpdated(LanguageCacheRefresher sender, CacheRefresherEventArgs e) + public void Handle(LanguageCacheRefresherNotification args) { - if (!(e.MessageObject is LanguageCacheRefresher.JsonPayload[] payloads)) + if (s_deactivate_handlers) + { + return;; + } + + if (!(args.MessageObject is LanguageCacheRefresher.JsonPayload[] payloads)) { return; } @@ -393,8 +404,13 @@ namespace Umbraco.Cms.Infrastructure.Search /// /// /// - private void ContentTypeCacheRefresherUpdated(ContentTypeCacheRefresher sender, CacheRefresherEventArgs args) + public void Handle(ContentTypeCacheRefresherNotification args) { + if (s_deactivate_handlers) + { + return;; + } + if (Suspendable.ExamineEvents.CanIndex == false) { return; @@ -668,34 +684,34 @@ namespace Umbraco.Cms.Infrastructure.Search private class DeferedReIndexForContent : DeferedAction { private readonly TaskHelper _taskHelper; - private readonly ExamineComponent _examineComponent; + private readonly ExamineNotificationHandler _ExamineNotificationHandler; private readonly IContent _content; private readonly bool _isPublished; - public DeferedReIndexForContent(TaskHelper taskHelper, ExamineComponent examineComponent, IContent content, bool isPublished) + public DeferedReIndexForContent(TaskHelper taskHelper, ExamineNotificationHandler ExamineNotificationHandler, IContent content, bool isPublished) { _taskHelper = taskHelper; - _examineComponent = examineComponent; + _ExamineNotificationHandler = ExamineNotificationHandler; _content = content; _isPublished = isPublished; } - public override void Execute() => Execute(_taskHelper, _examineComponent, _content, _isPublished); + public override void Execute() => Execute(_taskHelper, _ExamineNotificationHandler, _content, _isPublished); - public static void Execute(TaskHelper taskHelper, ExamineComponent examineComponent, IContent content, bool isPublished) + public static void Execute(TaskHelper taskHelper, ExamineNotificationHandler ExamineNotificationHandler, IContent content, bool isPublished) => taskHelper.RunBackgroundTask(() => { - using IScope scope = examineComponent._scopeProvider.CreateScope(autoComplete: true); + using IScope scope = ExamineNotificationHandler._scopeProvider.CreateScope(autoComplete: true); // for content we have a different builder for published vs unpublished // we don't want to build more value sets than is needed so we'll lazily build 2 one for published one for non-published var builders = new Dictionary>> { - [true] = new Lazy>(() => examineComponent._publishedContentValueSetBuilder.GetValueSets(content).ToList()), - [false] = new Lazy>(() => examineComponent._contentValueSetBuilder.GetValueSets(content).ToList()) + [true] = new Lazy>(() => ExamineNotificationHandler._publishedContentValueSetBuilder.GetValueSets(content).ToList()), + [false] = new Lazy>(() => ExamineNotificationHandler._contentValueSetBuilder.GetValueSets(content).ToList()) }; - foreach (IUmbracoIndex index in examineComponent._examineManager.Indexes.OfType() + foreach (IUmbracoIndex index in ExamineNotificationHandler._examineManager.Indexes.OfType() //filter the indexers .Where(x => isPublished || !x.PublishedValuesOnly) .Where(x => x.EnableDefaultEventHandler)) @@ -714,29 +730,29 @@ namespace Umbraco.Cms.Infrastructure.Search private class DeferedReIndexForMedia : DeferedAction { private readonly TaskHelper _taskHelper; - private readonly ExamineComponent _examineComponent; + private readonly ExamineNotificationHandler _ExamineNotificationHandler; private readonly IMedia _media; private readonly bool _isPublished; - public DeferedReIndexForMedia(TaskHelper taskHelper, ExamineComponent examineComponent, IMedia media, bool isPublished) + public DeferedReIndexForMedia(TaskHelper taskHelper, ExamineNotificationHandler ExamineNotificationHandler, IMedia media, bool isPublished) { _taskHelper = taskHelper; - _examineComponent = examineComponent; + _ExamineNotificationHandler = ExamineNotificationHandler; _media = media; _isPublished = isPublished; } - public override void Execute() => Execute(_taskHelper, _examineComponent, _media, _isPublished); + public override void Execute() => Execute(_taskHelper, _ExamineNotificationHandler, _media, _isPublished); - public static void Execute(TaskHelper taskHelper, ExamineComponent examineComponent, IMedia media, bool isPublished) => + public static void Execute(TaskHelper taskHelper, ExamineNotificationHandler ExamineNotificationHandler, IMedia media, bool isPublished) => // perform the ValueSet lookup on a background thread taskHelper.RunBackgroundTask(() => { - using IScope scope = examineComponent._scopeProvider.CreateScope(autoComplete: true); + using IScope scope = ExamineNotificationHandler._scopeProvider.CreateScope(autoComplete: true); - var valueSet = examineComponent._mediaValueSetBuilder.GetValueSets(media).ToList(); + var valueSet = ExamineNotificationHandler._mediaValueSetBuilder.GetValueSets(media).ToList(); - foreach (IUmbracoIndex index in examineComponent._examineManager.Indexes.OfType() + foreach (IUmbracoIndex index in ExamineNotificationHandler._examineManager.Indexes.OfType() //filter the indexers .Where(x => isPublished || !x.PublishedValuesOnly) .Where(x => x.EnableDefaultEventHandler)) @@ -753,27 +769,27 @@ namespace Umbraco.Cms.Infrastructure.Search /// private class DeferedReIndexForMember : DeferedAction { - private readonly ExamineComponent _examineComponent; + private readonly ExamineNotificationHandler _ExamineNotificationHandler; private readonly IMember _member; private readonly TaskHelper _taskHelper; - public DeferedReIndexForMember(TaskHelper taskHelper, ExamineComponent examineComponent, IMember member) + public DeferedReIndexForMember(TaskHelper taskHelper, ExamineNotificationHandler ExamineNotificationHandler, IMember member) { - _examineComponent = examineComponent; + _ExamineNotificationHandler = ExamineNotificationHandler; _member = member; _taskHelper = taskHelper; } - public override void Execute() => Execute(_taskHelper, _examineComponent, _member); + public override void Execute() => Execute(_taskHelper, _ExamineNotificationHandler, _member); - public static void Execute(TaskHelper taskHelper, ExamineComponent examineComponent, IMember member) => + public static void Execute(TaskHelper taskHelper, ExamineNotificationHandler ExamineNotificationHandler, IMember member) => // perform the ValueSet lookup on a background thread taskHelper.RunBackgroundTask(() => { - using IScope scope = examineComponent._scopeProvider.CreateScope(autoComplete: true); + using IScope scope = ExamineNotificationHandler._scopeProvider.CreateScope(autoComplete: true); - var valueSet = examineComponent._memberValueSetBuilder.GetValueSets(member).ToList(); - foreach (IUmbracoIndex index in examineComponent._examineManager.Indexes.OfType() + var valueSet = ExamineNotificationHandler._memberValueSetBuilder.GetValueSets(member).ToList(); + foreach (IUmbracoIndex index in ExamineNotificationHandler._examineManager.Indexes.OfType() //filter the indexers .Where(x => x.EnableDefaultEventHandler)) { @@ -786,23 +802,23 @@ namespace Umbraco.Cms.Infrastructure.Search private class DeferedDeleteIndex : DeferedAction { - private readonly ExamineComponent _examineComponent; + private readonly ExamineNotificationHandler _ExamineNotificationHandler; private readonly int _id; private readonly bool _keepIfUnpublished; - public DeferedDeleteIndex(ExamineComponent examineComponent, int id, bool keepIfUnpublished) + public DeferedDeleteIndex(ExamineNotificationHandler ExamineNotificationHandler, int id, bool keepIfUnpublished) { - _examineComponent = examineComponent; + _ExamineNotificationHandler = ExamineNotificationHandler; _id = id; _keepIfUnpublished = keepIfUnpublished; } - public override void Execute() => Execute(_examineComponent, _id, _keepIfUnpublished); + public override void Execute() => Execute(_ExamineNotificationHandler, _id, _keepIfUnpublished); - public static void Execute(ExamineComponent examineComponent, int id, bool keepIfUnpublished) + public static void Execute(ExamineNotificationHandler ExamineNotificationHandler, int id, bool keepIfUnpublished) { var strId = id.ToString(CultureInfo.InvariantCulture); - foreach (var index in examineComponent._examineManager.Indexes.OfType() + foreach (var index in ExamineNotificationHandler._examineManager.Indexes.OfType() .Where(x => x.PublishedValuesOnly || !keepIfUnpublished) .Where(x => x.EnableDefaultEventHandler)) { @@ -811,7 +827,5 @@ namespace Umbraco.Cms.Infrastructure.Search } } #endregion - - } } diff --git a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs index e73c0a5c5f..dbf047cf48 100644 --- a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs +++ b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs @@ -25,7 +25,6 @@ using Umbraco.Cms.Core.Configuration.Models; using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.IO; using Umbraco.Cms.Core.Scoping; -using Umbraco.Cms.Core.Security; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Strings; using Umbraco.Cms.Core.Web; @@ -217,6 +216,7 @@ namespace Umbraco.Cms.Tests.Integration.Testing .AddBackOfficeAuthentication() .AddBackOfficeIdentity() .AddMembersIdentity() + .AddExamine() .AddTestServices(TestHelper, GetAppCaches()); if (TestOptions.Mapper) diff --git a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEventsTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEventsTests.cs index c26d2e0e7b..0cf091ac65 100644 --- a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEventsTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEventsTests.cs @@ -8,7 +8,10 @@ using System.Collections.Generic; using System.Linq; using Microsoft.Extensions.Logging; using NUnit.Framework; +using Umbraco.Cms.Core; using Umbraco.Cms.Core.Cache; +using Umbraco.Cms.Core.DependencyInjection; +using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Sync; using Umbraco.Cms.Core.Web; @@ -18,7 +21,6 @@ using Umbraco.Cms.Tests.Common.Builders; using Umbraco.Cms.Tests.Common.Testing; using Umbraco.Cms.Tests.Integration.Testing; using Umbraco.Extensions; -using Constants = Umbraco.Cms.Core.Constants; namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services { @@ -34,6 +36,40 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services #region Setup + private class TestNotificationHandler : INotificationHandler + { + public void Handle(ContentCacheRefresherNotification args) + { + // reports the event as: "ContentCache/,.../X + // where + // is(are) the action(s) + // X is the event content ID + if (args.MessageType != MessageType.RefreshByPayload) + { + throw new NotSupportedException(); + } + + foreach (ContentCacheRefresher.JsonPayload payload in (ContentCacheRefresher.JsonPayload[])args.MessageObject) + { + var e = new EventInstance + { + Message = _msgCount, + Sender = "ContentCacheRefresher", + EventArgs = payload, + Name = payload.ChangeTypes.ToString().Replace(" ", string.Empty), + Args = payload.Id.ToInvariantString() + }; + _events.Add(e); + } + + _msgCount++; + } + } + protected override void CustomTestSetup(IUmbracoBuilder builder) + { + builder.AddNotificationHandler(); + } + [SetUp] public void SetUp() { @@ -45,7 +81,6 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services DocumentRepository.ScopedEntityRefresh += ContentRepositoryRefreshed; DocumentRepository.ScopeEntityRemove += ContentRepositoryRemoved; DocumentRepository.ScopeVersionRemove += ContentRepositoryRemovedVersion; - ContentCacheRefresher.CacheUpdated += ContentCacheUpdated; // prepare content type Template template = TemplateBuilder.CreateTextPageTemplate(); @@ -66,12 +101,11 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services DocumentRepository.ScopedEntityRefresh -= ContentRepositoryRefreshed; DocumentRepository.ScopeEntityRemove -= ContentRepositoryRemoved; DocumentRepository.ScopeVersionRemove -= ContentRepositoryRemovedVersion; - ContentCacheRefresher.CacheUpdated -= ContentCacheUpdated; } private DistributedCacheBinder _distributedCacheBinder; - private IList _events; - private int _msgCount; + private static IList _events; + private static int _msgCount; private IContentType _contentType; private void ResetEvents() @@ -324,32 +358,7 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services _events.Add(e); } - private void ContentCacheUpdated(ContentCacheRefresher sender, CacheRefresherEventArgs args) - { - // reports the event as: "ContentCache/,.../X - // where - // is(are) the action(s) - // X is the event content ID - if (args.MessageType != MessageType.RefreshByPayload) - { - throw new NotSupportedException(); - } - foreach (ContentCacheRefresher.JsonPayload payload in (ContentCacheRefresher.JsonPayload[])args.MessageObject) - { - var e = new EventInstance - { - Message = _msgCount, - Sender = sender.Name, - EventArgs = payload, - Name = payload.ChangeTypes.ToString().Replace(" ", string.Empty), - Args = payload.Id.ToInvariantString() - }; - _events.Add(e); - } - - _msgCount++; - } private void WriteEvents() { diff --git a/src/Umbraco.Web.BackOffice/DependencyInjection/UmbracoBuilderExtensions.cs b/src/Umbraco.Web.BackOffice/DependencyInjection/UmbracoBuilderExtensions.cs index 098b2ba879..5356bc08f1 100644 --- a/src/Umbraco.Web.BackOffice/DependencyInjection/UmbracoBuilderExtensions.cs +++ b/src/Umbraco.Web.BackOffice/DependencyInjection/UmbracoBuilderExtensions.cs @@ -5,11 +5,11 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Umbraco.Cms.Core; +using Umbraco.Cms.Core.Cache; using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Hosting; using Umbraco.Cms.Core.IO; using Umbraco.Cms.Core.Services; -using Umbraco.Cms.Core.WebAssets; using Umbraco.Cms.Infrastructure.DependencyInjection; using Umbraco.Cms.Infrastructure.WebAssets; using Umbraco.Cms.Web.BackOffice.Controllers; @@ -19,6 +19,7 @@ using Umbraco.Cms.Web.BackOffice.ModelsBuilder; using Umbraco.Cms.Web.BackOffice.Routing; using Umbraco.Cms.Web.BackOffice.Security; using Umbraco.Cms.Web.BackOffice.Services; +using Umbraco.Cms.Web.BackOffice.SignalR; using Umbraco.Cms.Web.BackOffice.Trees; using Umbraco.Cms.Web.Common.Authorization; @@ -49,7 +50,8 @@ namespace Umbraco.Extensions .AddHostedServices() .AddDistributedCache() .AddModelsBuilderDashboard() - .AddUnattedInstallCreateUser(); + .AddUnattedInstallCreateUser() + .AddExamine(); /// /// Adds Umbraco back office authentication requirements @@ -153,6 +155,7 @@ namespace Umbraco.Extensions builder.Services.AddUnique(); builder.Services.AddUnique(); builder.Services.AddUnique(); + builder.AddNotificationAsyncHandler(); builder.Services.AddUnique(); builder.Services.AddScoped(); builder.Services.AddScoped(); diff --git a/src/Umbraco.Web.BackOffice/SignalR/PreviewHubComposer.cs b/src/Umbraco.Web.BackOffice/SignalR/PreviewHubComposer.cs deleted file mode 100644 index 18b8f90825..0000000000 --- a/src/Umbraco.Web.BackOffice/SignalR/PreviewHubComposer.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Umbraco.Cms.Core.Composing; -using Umbraco.Cms.Core.DependencyInjection; - -namespace Umbraco.Cms.Web.BackOffice.SignalR -{ - public class PreviewHubComposer : ComponentComposer, ICoreComposer - { - public override void Compose(IUmbracoBuilder builder) - { - base.Compose(builder); - } - } -} diff --git a/src/Umbraco.Web.BackOffice/SignalR/PreviewHubComponent.cs b/src/Umbraco.Web.BackOffice/SignalR/PreviewHubUpdater.cs similarity index 54% rename from src/Umbraco.Web.BackOffice/SignalR/PreviewHubComponent.cs rename to src/Umbraco.Web.BackOffice/SignalR/PreviewHubUpdater.cs index 00d3dc8013..a71b5439d4 100644 --- a/src/Umbraco.Web.BackOffice/SignalR/PreviewHubComponent.cs +++ b/src/Umbraco.Web.BackOffice/SignalR/PreviewHubUpdater.cs @@ -1,38 +1,26 @@ using System; +using System.Threading; +using System.Threading.Tasks; using Microsoft.AspNetCore.SignalR; using Umbraco.Cms.Core.Cache; -using Umbraco.Cms.Core.Composing; +using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Sync; namespace Umbraco.Cms.Web.BackOffice.SignalR { - public class PreviewHubComponent : IComponent + public class PreviewHubUpdater :INotificationAsyncHandler { private readonly Lazy> _hubContext; // using a lazy arg here means that we won't create the hub until necessary // and therefore we won't have too bad an impact on boot time - public PreviewHubComponent(Lazy> hubContext) + public PreviewHubUpdater(Lazy> hubContext) { _hubContext = hubContext; } - public void Initialize() - { - // ContentService.Saved is too soon - the content cache is not ready yet, - // so use the content cache refresher event, because when it triggers - // the cache has already been notified of the changes - ContentCacheRefresher.CacheUpdated += HandleCacheUpdated; - } - - public void Terminate() - { - ContentCacheRefresher.CacheUpdated -= HandleCacheUpdated; - } - - private async void HandleCacheUpdated(ContentCacheRefresher sender, CacheRefresherEventArgs args) - { + public async Task HandleAsync(ContentCacheRefresherNotification args, CancellationToken cancellationToken) { if (args.MessageType != MessageType.RefreshByPayload) return; var payloads = (ContentCacheRefresher.JsonPayload[])args.MessageObject; var hubContextInstance = _hubContext.Value; diff --git a/src/Umbraco.Web.Common/ModelsBuilder/DependencyInjection/UmbracoBuilderDependencyInjectionExtensions.cs b/src/Umbraco.Web.Common/ModelsBuilder/DependencyInjection/UmbracoBuilderDependencyInjectionExtensions.cs index 5ce05e62cd..e8b54d3af0 100644 --- a/src/Umbraco.Web.Common/ModelsBuilder/DependencyInjection/UmbracoBuilderDependencyInjectionExtensions.cs +++ b/src/Umbraco.Web.Common/ModelsBuilder/DependencyInjection/UmbracoBuilderDependencyInjectionExtensions.cs @@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Mvc.Razor; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Cache; using Umbraco.Cms.Core.Configuration; using Umbraco.Cms.Core.Configuration.Models; using Umbraco.Cms.Core.DependencyInjection; @@ -102,10 +103,15 @@ namespace Umbraco.Extensions builder.AddNotificationHandler(); builder.AddNotificationHandler(); builder.AddNotificationHandler(); - builder.AddNotificationHandler(); + builder.AddNotificationHandler(); + builder.AddNotificationHandler(); + builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); + builder.AddNotificationHandler(); + builder.AddNotificationHandler(); + builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton();