Merge pull request #10946 from umbraco/v9/feature/validationService-optimization
V9: Reuse value editors for validation
This commit is contained in:
12
src/Umbraco.Core/Cache/IValueEditorCache.cs
Normal file
12
src/Umbraco.Core/Cache/IValueEditorCache.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Cms.Core.Cache
|
||||
{
|
||||
public interface IValueEditorCache
|
||||
{
|
||||
public IDataValueEditor GetValueEditor(IDataEditor dataEditor, IDataType dataType);
|
||||
public void ClearCache(IEnumerable<int> dataTypeIds);
|
||||
}
|
||||
}
|
||||
61
src/Umbraco.Core/Cache/ValueEditorCache.cs
Normal file
61
src/Umbraco.Core/Cache/ValueEditorCache.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Cms.Core.Cache
|
||||
{
|
||||
public class ValueEditorCache : IValueEditorCache
|
||||
{
|
||||
private readonly Dictionary<string, Dictionary<int, IDataValueEditor>> _valueEditorCache;
|
||||
private readonly object _dictionaryLocker;
|
||||
|
||||
public ValueEditorCache()
|
||||
{
|
||||
_valueEditorCache = new Dictionary<string, Dictionary<int, IDataValueEditor>>();
|
||||
_dictionaryLocker = new object();
|
||||
}
|
||||
|
||||
public IDataValueEditor GetValueEditor(IDataEditor editor, IDataType dataType)
|
||||
{
|
||||
// Lock just in case multiple threads uses the cache at the same time.
|
||||
lock (_dictionaryLocker)
|
||||
{
|
||||
// We try and get the dictionary based on the IDataEditor alias,
|
||||
// this is here just in case a data type can have more than one value data editor.
|
||||
// If this is not the case this could be simplified quite a bit, by just using the inner dictionary only.
|
||||
IDataValueEditor valueEditor;
|
||||
if (_valueEditorCache.TryGetValue(editor.Alias, out Dictionary<int, IDataValueEditor> dataEditorCache))
|
||||
{
|
||||
if (dataEditorCache.TryGetValue(dataType.Id, out valueEditor))
|
||||
{
|
||||
return valueEditor;
|
||||
}
|
||||
|
||||
valueEditor = editor.GetValueEditor(dataType.Configuration);
|
||||
dataEditorCache[dataType.Id] = valueEditor;
|
||||
return valueEditor;
|
||||
}
|
||||
|
||||
valueEditor = editor.GetValueEditor(dataType.Configuration);
|
||||
_valueEditorCache[editor.Alias] = new Dictionary<int, IDataValueEditor> { [dataType.Id] = valueEditor };
|
||||
return valueEditor;
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearCache(IEnumerable<int> dataTypeIds)
|
||||
{
|
||||
lock (_dictionaryLocker)
|
||||
{
|
||||
// If a datatype is saved or deleted we have to clear any value editors based on their ID from the cache,
|
||||
// since it could mean that their configuration has changed.
|
||||
foreach (var id in dataTypeIds)
|
||||
{
|
||||
foreach (Dictionary<int, IDataValueEditor> editors in _valueEditorCache.Values)
|
||||
{
|
||||
editors.Remove(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
57
src/Umbraco.Core/Cache/ValueEditorCacheRefresher.cs
Normal file
57
src/Umbraco.Core/Cache/ValueEditorCacheRefresher.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Cms.Core.Events;
|
||||
using Umbraco.Cms.Core.Notifications;
|
||||
using Umbraco.Cms.Core.Serialization;
|
||||
|
||||
namespace Umbraco.Cms.Core.Cache
|
||||
{
|
||||
public sealed class ValueEditorCacheRefresher : PayloadCacheRefresherBase<DataTypeCacheRefresherNotification, DataTypeCacheRefresher.JsonPayload>
|
||||
{
|
||||
private readonly IValueEditorCache _valueEditorCache;
|
||||
|
||||
public ValueEditorCacheRefresher(
|
||||
AppCaches appCaches,
|
||||
IJsonSerializer serializer,
|
||||
IEventAggregator eventAggregator,
|
||||
ICacheRefresherNotificationFactory factory,
|
||||
IValueEditorCache valueEditorCache) : base(appCaches, serializer, eventAggregator, factory)
|
||||
{
|
||||
_valueEditorCache = valueEditorCache;
|
||||
}
|
||||
|
||||
public static readonly Guid UniqueId = Guid.Parse("D28A1DBB-2308-4918-9A92-2F8689B6CBFE");
|
||||
public override Guid RefresherUniqueId => UniqueId;
|
||||
public override string Name => "ValueEditorCacheRefresher";
|
||||
|
||||
public override void Refresh(DataTypeCacheRefresher.JsonPayload[] payloads)
|
||||
{
|
||||
IEnumerable<int> ids = payloads.Select(x => x.Id);
|
||||
_valueEditorCache.ClearCache(ids);
|
||||
}
|
||||
|
||||
// these events should never trigger
|
||||
// everything should be PAYLOAD/JSON
|
||||
|
||||
public override void RefreshAll()
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void Refresh(int id)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void Refresh(Guid id)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void Remove(int id)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -253,6 +253,9 @@ namespace Umbraco.Cms.Core.DependencyInjection
|
||||
|
||||
// register a basic/noop published snapshot service to be replaced
|
||||
Services.AddSingleton<IPublishedSnapshotService, InternalPublishedSnapshotService>();
|
||||
|
||||
// Register ValueEditorCache used for validation
|
||||
Services.AddSingleton<IValueEditorCache, ValueEditorCache>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user