Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/Umbraco.Core/Cache/ValueEditorCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ public void ClearCache(IEnumerable<int> dataTypeIds)
{
foreach (Dictionary<int, IDataValueEditor> editors in _valueEditorCache.Values)
{
if (editors[id] is IDisposable disposable)
{
disposable.Dispose();
}

editors.Remove(id);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,17 @@ namespace Umbraco.Cms.Core.PropertyEditors;
/// <summary>
/// The value editor for the file upload property editor.
/// </summary>
internal class FileUploadPropertyValueEditor : DataValueEditor
/// <remarks>
/// As this class is not registered with DI as a singleton, it must be disposed to release
/// the settings change subscription and avoid a memory leak.
/// </remarks>
internal class FileUploadPropertyValueEditor : DataValueEditor, IDisposable
{
private readonly MediaFileManager _mediaFileManager;
private readonly IFileStreamSecurityValidator _fileStreamSecurityValidator;

private ContentSettings _contentSettings;
private readonly IDisposable? _contentSettingsChangeSubscription;

public FileUploadPropertyValueEditor(
DataEditorAttribute attribute,
Expand All @@ -36,7 +42,7 @@ public FileUploadPropertyValueEditor(
_mediaFileManager = mediaFileManager ?? throw new ArgumentNullException(nameof(mediaFileManager));
_fileStreamSecurityValidator = fileStreamSecurityValidator;
_contentSettings = contentSettings.CurrentValue ?? throw new ArgumentNullException(nameof(contentSettings));
contentSettings.OnChange(x => _contentSettings = x);
_contentSettingsChangeSubscription = contentSettings.OnChange(x => _contentSettings = x);
}

/// <summary>
Expand Down Expand Up @@ -163,4 +169,6 @@ public FileUploadPropertyValueEditor(

return filepath;
}

public void Dispose() => _contentSettingsChangeSubscription?.Dispose();
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ namespace Umbraco.Cms.Core.PropertyEditors;
/// <summary>
/// Represents an image cropper property editor.
/// </summary>
/// <remarks>
/// As this class is not registered with DI as a singleton, it must be disposed to release
/// the settings change subscription and avoid a memory leak.
/// </remarks>
[DataEditor(
Constants.PropertyEditors.Aliases.ImageCropper,
"Image Cropper",
Expand All @@ -33,7 +37,7 @@ namespace Umbraco.Cms.Core.PropertyEditors;
public class ImageCropperPropertyEditor : DataEditor, IMediaUrlGenerator,
INotificationHandler<ContentCopiedNotification>, INotificationHandler<ContentDeletedNotification>,
INotificationHandler<MediaDeletedNotification>, INotificationHandler<MediaSavingNotification>,
INotificationHandler<MemberDeletedNotification>
INotificationHandler<MemberDeletedNotification>, IDisposable
{
private readonly UploadAutoFillProperties _autoFillProperties;
private readonly IContentService _contentService;
Expand All @@ -42,7 +46,9 @@ public class ImageCropperPropertyEditor : DataEditor, IMediaUrlGenerator,
private readonly IIOHelper _ioHelper;
private readonly ILogger<ImageCropperPropertyEditor> _logger;
private readonly MediaFileManager _mediaFileManager;

private ContentSettings _contentSettings;
private readonly IDisposable? _contentSettingsChangeSubscription;

// Scheduled for removal in v12
[Obsolete("Please use constructor that takes an IEditorConfigurationParser instead")]
Expand Down Expand Up @@ -93,7 +99,7 @@ public ImageCropperPropertyEditor(
_editorConfigurationParser = editorConfigurationParser;
_logger = loggerFactory.CreateLogger<ImageCropperPropertyEditor>();

contentSettings.OnChange(x => _contentSettings = x);
_contentSettingsChangeSubscription = contentSettings.OnChange(x => _contentSettings = x);
SupportsReadOnly = true;
}

Expand Down Expand Up @@ -352,4 +358,6 @@ private void AutoFillProperties(IContentBase model)
}
}
}

public void Dispose() => _contentSettingsChangeSubscription?.Dispose();
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,19 @@ namespace Umbraco.Cms.Core.PropertyEditors;
/// <summary>
/// The value editor for the image cropper property editor.
/// </summary>
internal class ImageCropperPropertyValueEditor : DataValueEditor // TODO: core vs web?
/// <remarks>
/// As this class is not registered with DI as a singleton, it must be disposed to release
/// the settings change subscription and avoid a memory leak.
/// </remarks>
internal class ImageCropperPropertyValueEditor : DataValueEditor, IDisposable
{
private readonly IDataTypeConfigurationCache _dataTypeConfigurationCache;
private readonly IFileStreamSecurityValidator _fileStreamSecurityValidator;
private readonly ILogger<ImageCropperPropertyValueEditor> _logger;
private readonly MediaFileManager _mediaFileManager;

private ContentSettings _contentSettings;
private readonly IDisposable? _contentSettingsChangeSubscription;

public ImageCropperPropertyValueEditor(
DataEditorAttribute attribute,
Expand All @@ -49,7 +55,7 @@ public ImageCropperPropertyValueEditor(
_contentSettings = contentSettings.CurrentValue;
_dataTypeConfigurationCache = dataTypeConfigurationCache;
_fileStreamSecurityValidator = fileStreamSecurityValidator;
contentSettings.OnChange(x => _contentSettings = x);
_contentSettingsChangeSubscription = contentSettings.OnChange(x => _contentSettings = x);
}

/// <summary>
Expand Down Expand Up @@ -252,4 +258,6 @@ public override string ConvertDbToString(IPropertyType propertyType, object? val

return filepath;
}

public void Dispose() => _contentSettingsChangeSubscription?.Dispose();
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,19 @@

namespace Umbraco.Cms.Core.PropertyEditors;

internal class UploadFileTypeValidator : IValueValidator
/// <summary>
/// The value editor for file upload property editors.
/// </summary>
/// <remarks>
/// As this class is not registered with DI as a singleton, it must be disposed to release
/// the settings change subscription and avoid a memory leak.
/// </remarks>
internal class UploadFileTypeValidator : IValueValidator, IDisposable
{
private readonly ILocalizedTextService _localizedTextService;

private ContentSettings _contentSettings;
private readonly IDisposable? _contentSettingsChangeSubscription;

public UploadFileTypeValidator(
ILocalizedTextService localizedTextService,
Expand All @@ -23,7 +32,7 @@ public UploadFileTypeValidator(
_localizedTextService = localizedTextService;
_contentSettings = contentSettings.CurrentValue;

contentSettings.OnChange(x => _contentSettings = x);
_contentSettingsChangeSubscription = contentSettings.OnChange(x => _contentSettings = x);
}

public IEnumerable<ValidationResult> Validate(object? value, string? valueType, object? dataTypeConfiguration)
Expand Down Expand Up @@ -103,4 +112,6 @@ internal static bool TryGetFileExtension(string? fileName, [MaybeNullWhen(false)
extension = fileName.GetFileExtension().TrimStart(".");
return true;
}

public void Dispose() => _contentSettingsChangeSubscription?.Dispose();
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,12 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters;
/// A value converter for TinyMCE that will ensure any macro content is rendered properly even when
/// used dynamically.
/// </summary>
/// <remarks>
/// As this class is not registered with DI as a singleton, it must be disposed to release
/// the settings change subscription and avoid a memory leak.
/// </remarks>
[DefaultPropertyValueConverter]
public class RteMacroRenderingValueConverter : SimpleTinyMceValueConverter, IDeliveryApiPropertyValueConverter
public class RteMacroRenderingValueConverter : SimpleTinyMceValueConverter, IDeliveryApiPropertyValueConverter, IDisposable
{
private readonly HtmlImageSourceParser _imageSourceParser;
private readonly HtmlLocalLinkParser _linkParser;
Expand All @@ -47,7 +51,9 @@ public class RteMacroRenderingValueConverter : SimpleTinyMceValueConverter, IDel
private readonly ILogger<RteMacroRenderingValueConverter> _logger;
private readonly IApiElementBuilder _apiElementBuilder;
private readonly RichTextBlockPropertyValueConstructorCache _constructorCache;

private DeliveryApiSettings _deliveryApiSettings;
private readonly IDisposable? _deliveryApiSettingsChangeSubscription;

[Obsolete("Please use the constructor that takes all arguments. Will be removed in V14.")]
public RteMacroRenderingValueConverter(IUmbracoContextAccessor umbracoContextAccessor, IMacroRenderer macroRenderer,
Expand Down Expand Up @@ -107,8 +113,9 @@ public RteMacroRenderingValueConverter(IUmbracoContextAccessor umbracoContextAcc
_apiElementBuilder = apiElementBuilder;
_constructorCache = constructorCache;
_logger = logger;

_deliveryApiSettings = deliveryApiSettingsMonitor.CurrentValue;
deliveryApiSettingsMonitor.OnChange(settings => _deliveryApiSettings = settings);
_deliveryApiSettingsChangeSubscription = deliveryApiSettingsMonitor.OnChange(settings => _deliveryApiSettings = settings);
}

public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType) =>
Expand Down Expand Up @@ -314,4 +321,6 @@ private class RichTextEditorIntermediateValue : IRichTextEditorIntermediateValue

public required RichTextBlockModel? RichTextBlockModel { get; set; }
}

public void Dispose() => _deliveryApiSettingsChangeSubscription?.Dispose();
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Configuration.Models;
Expand All @@ -17,7 +17,7 @@ internal sealed class DeliveryApiContentIndexingNotificationHandler :
{
private readonly IDeliveryApiIndexingHandler _deliveryApiIndexingHandler;
private readonly ILogger<DeliveryApiContentIndexingNotificationHandler> _logger;
private DeliveryApiSettings _deliveryApiSettings;
private readonly DeliveryApiSettings _deliveryApiSettings;

public DeliveryApiContentIndexingNotificationHandler(
IDeliveryApiIndexingHandler deliveryApiIndexingHandler,
Expand All @@ -27,7 +27,6 @@ public DeliveryApiContentIndexingNotificationHandler(
_deliveryApiIndexingHandler = deliveryApiIndexingHandler;
_logger = logger;
_deliveryApiSettings = deliveryApiSettings.CurrentValue;
deliveryApiSettings.OnChange(settings => _deliveryApiSettings = settings);
}

public void Handle(ContentCacheRefresherNotification notification)
Expand Down
9 changes: 3 additions & 6 deletions src/Umbraco.Web.BackOffice/Controllers/HelpController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using Newtonsoft.Json;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Web.Common.Attributes;

namespace Umbraco.Cms.Web.BackOffice.Controllers;
Expand All @@ -16,7 +15,8 @@ public class HelpController : UmbracoAuthorizedJsonController
{
private static HttpClient? _httpClient;
private readonly ILogger<HelpController> _logger;
private HelpPageSettings? _helpPageSettings;

private readonly HelpPageSettings? _helpPageSettings;

[ActivatorUtilitiesConstructor]
public HelpController(
Expand All @@ -25,12 +25,9 @@ public HelpController(
{
_logger = logger;

ResetHelpPageSettings(helpPageSettings.CurrentValue);
helpPageSettings.OnChange(ResetHelpPageSettings);
_helpPageSettings = helpPageSettings.CurrentValue;
}

private void ResetHelpPageSettings(HelpPageSettings settings) => _helpPageSettings = settings;

public async Task<List<HelpPage>> GetContextHelpForPage(string section, string tree,
string baseUrl = "https://our.umbraco.com")
{
Expand Down
4 changes: 1 addition & 3 deletions src/Umbraco.Web.BackOffice/Controllers/ImagesController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class ImagesController : UmbracoAuthorizedApiController
{
private readonly MediaFileManager _mediaFileManager;
private readonly IImageUrlGenerator _imageUrlGenerator;
private ContentSettings _contentSettings;
private readonly ContentSettings _contentSettings;

[Obsolete("Use non obsolete-constructor. Scheduled for removal in Umbraco 13.")]
public ImagesController(
Expand All @@ -45,8 +45,6 @@ public ImagesController(
_mediaFileManager = mediaFileManager;
_imageUrlGenerator = imageUrlGenerator;
_contentSettings = contentSettingsMonitor.CurrentValue;

contentSettingsMonitor.OnChange(x => _contentSettings = x);
}

/// <summary>
Expand Down
Loading