Merge remote-tracking branch 'origin/v9/dev' into netcore/feature/get_rid_of_ICoreComposer

# Conflicts:
#	src/Umbraco.Examine.Lucene/ExamineLuceneComposer.cs
#	src/Umbraco.Examine.Lucene/ExamineLuceneConfigureIndexes.cs
#	src/Umbraco.Examine.Lucene/ExamineLuceneFinalComposer.cs
#	src/Umbraco.Examine.Lucene/ExamineLuceneStarting.cs
#	src/Umbraco.Infrastructure/Compose/NotificationsComposer.cs
#	src/Umbraco.PublishedCache.NuCache/Compose/NotificationsComposer.cs
#	src/Umbraco.Web.BackOffice/DependencyInjection/UmbracoBuilderExtensions.cs
#	src/Umbraco.Web.UI.Client/package-lock.json
This commit is contained in:
Bjarke Berg
2021-06-15 19:10:30 +02:00
969 changed files with 28924 additions and 24595 deletions

View File

@@ -21,6 +21,7 @@ using Umbraco.Cms.Core.Mail;
using Umbraco.Cms.Core.Manifest;
using Umbraco.Cms.Core.Media;
using Umbraco.Cms.Core.Models.PublishedContent;
using Umbraco.Cms.Core.Notifications;
using Umbraco.Cms.Core.Packaging;
using Umbraco.Cms.Core.PropertyEditors;
using Umbraco.Cms.Core.PropertyEditors.ValueConverters;
@@ -30,7 +31,6 @@ using Umbraco.Cms.Core.Runtime;
using Umbraco.Cms.Core.Scoping;
using Umbraco.Cms.Core.Serialization;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.Notifications;
using Umbraco.Cms.Core.Strings;
using Umbraco.Cms.Core.Templates;
using Umbraco.Cms.Core.Trees;
@@ -164,8 +164,6 @@ namespace Umbraco.Cms.Infrastructure.DependencyInjection
builder.Services.AddUnique<IUmbracoComponentRenderer, UmbracoComponentRenderer>();
// Register noop versions for examine to be overridden by examine
builder.Services.AddUnique<IUmbracoIndexesCreator, NoopUmbracoIndexesCreator>();
builder.Services.AddUnique<IBackOfficeExamineSearcher, NoopBackOfficeExamineSearcher>();
builder.Services.AddUnique<UploadAutoFillProperties>();
@@ -180,7 +178,6 @@ namespace Umbraco.Cms.Infrastructure.DependencyInjection
// Services required to run background jobs (with out the handler)
builder.Services.AddUnique<IBackgroundTaskQueue, BackgroundTaskQueue>();
builder.Services.AddUnique<TaskHelper>();
return builder;
}
@@ -252,7 +249,7 @@ namespace Umbraco.Cms.Infrastructure.DependencyInjection
public static IUmbracoBuilder AddCoreNotifications(this IUmbracoBuilder builder)
{
// add handlers for sending user notifications (i.e. emails)
// add handlers for sending user notifications (i.e. emails)
builder.Services.AddUnique<UserNotificationsHandler.Notifier>();
builder
.AddNotificationHandler<ContentSavedNotification, UserNotificationsHandler>()

View File

@@ -3,6 +3,7 @@ using Microsoft.Extensions.DependencyInjection;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Notifications;
using Umbraco.Cms.Core.PublishedCache;
using Umbraco.Cms.Core.Services.Changes;
using Umbraco.Cms.Core.Sync;
@@ -26,10 +27,11 @@ namespace Umbraco.Cms.Infrastructure.DependencyInjection
/// </remarks>
public static IUmbracoBuilder AddDistributedCache(this IUmbracoBuilder builder)
{
builder.SetDatabaseServerMessengerCallbacks(GetCallbacks);
builder.Services.AddSingleton<LastSyncedFileManager>();
builder.Services.AddSingleton<ISyncBootStateAccessor, SyncBootStateAccessor>();
builder.SetServerMessenger<BatchedDatabaseServerMessenger>();
builder.AddNotificationHandler<UmbracoApplicationStarting, DatabaseServerMessengerNotificationHandler>();
builder.AddNotificationHandler<UmbracoRequestEnd, DatabaseServerMessengerNotificationHandler>();
builder.AddNotificationHandler<UmbracoApplicationStartingNotification, DatabaseServerMessengerNotificationHandler>();
builder.AddNotificationHandler<UmbracoRequestEndNotification, DatabaseServerMessengerNotificationHandler>();
return builder;
}
@@ -58,24 +60,6 @@ namespace Umbraco.Cms.Infrastructure.DependencyInjection
public static void SetServerRegistrar(this IUmbracoBuilder builder, IServerRoleAccessor registrar)
=> builder.Services.AddUnique(registrar);
/// <summary>
/// Sets the database server messenger options.
/// </summary>
/// <param name="builder">The builder.</param>
/// <param name="factory">A function creating the options.</param>
/// <remarks>Use DatabaseServerRegistrarAndMessengerComposer.GetDefaultOptions to get the options that Umbraco would use by default.</remarks>
public static void SetDatabaseServerMessengerCallbacks(this IUmbracoBuilder builder, Func<IServiceProvider, DatabaseServerMessengerCallbacks> factory)
=> builder.Services.AddUnique(factory);
/// <summary>
/// Sets the database server messenger options.
/// </summary>
/// <param name="builder">The builder.</param>
/// <param name="options">Options.</param>
/// <remarks>Use DatabaseServerRegistrarAndMessengerComposer.GetDefaultOptions to get the options that Umbraco would use by default.</remarks>
public static void SetDatabaseServerMessengerOptions(this IUmbracoBuilder builder, DatabaseServerMessengerCallbacks options)
=> builder.Services.AddUnique(options);
/// <summary>
/// Sets the server messenger.
/// </summary>
@@ -100,36 +84,5 @@ namespace Umbraco.Cms.Infrastructure.DependencyInjection
/// <param name="registrar">A server messenger.</param>
public static void SetServerMessenger(this IUmbracoBuilder builder, IServerMessenger registrar)
=> builder.Services.AddUnique(registrar);
private static DatabaseServerMessengerCallbacks GetCallbacks(IServiceProvider factory) => new DatabaseServerMessengerCallbacks
{
// These callbacks will be executed if the server has not been synced
// (i.e. it is a new server or the lastsynced.txt file has been removed)
InitializingCallbacks = new Action[]
{
// rebuild the xml cache file if the server is not synced
() =>
{
IPublishedSnapshotService publishedSnapshotService = factory.GetRequiredService<IPublishedSnapshotService>();
// rebuild the published snapshot caches entirely, if the server is not synced
// this is equivalent to DistributedCache RefreshAll... but local only
// (we really should have a way to reuse RefreshAll... locally)
// note: refresh all content & media caches does refresh content types too
publishedSnapshotService.Notify(new[] { new DomainCacheRefresher.JsonPayload(0, DomainChangeTypes.RefreshAll) });
publishedSnapshotService.Notify(new[] { new ContentCacheRefresher.JsonPayload(0, null, TreeChangeTypes.RefreshAll) }, out _, out _);
publishedSnapshotService.Notify(new[] { new MediaCacheRefresher.JsonPayload(0, null, TreeChangeTypes.RefreshAll) }, out _);
},
// rebuild indexes if the server is not synced
// NOTE: This will rebuild ALL indexes including the members, if developers want to target specific
// indexes then they can adjust this logic themselves.
() =>
{
var indexRebuilder = factory.GetRequiredService<BackgroundIndexRebuilder>();
indexRebuilder.RebuildIndexes(false, TimeSpan.FromSeconds(5));
}
}
};
}
}

View File

@@ -3,6 +3,7 @@ using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Notifications;
using Umbraco.Cms.Core.PropertyEditors;
using Umbraco.Cms.Core.Scoping;
using Umbraco.Cms.Core.Services;
@@ -27,7 +28,8 @@ namespace Umbraco.Cms.Infrastructure.DependencyInjection
builder.Services.AddSingleton<IIndexPopulator, PublishedContentIndexPopulator>();
builder.Services.AddSingleton<IIndexPopulator, MediaIndexPopulator>();
builder.Services.AddSingleton<IndexRebuilder>();
builder.Services.AddSingleton<IIndexRebuilder, ExamineIndexRebuilder>();
builder.Services.AddSingleton<IUmbracoIndexingHandler, ExamineUmbracoIndexingHandler>();
builder.Services.AddUnique<IUmbracoIndexConfig, UmbracoIndexConfig>();
builder.Services.AddUnique<IIndexDiagnosticsFactory, IndexDiagnosticsFactory>();
builder.Services.AddUnique<IPublishedContentValueSetBuilder>(factory =>
@@ -48,14 +50,15 @@ namespace Umbraco.Cms.Infrastructure.DependencyInjection
false));
builder.Services.AddUnique<IValueSetBuilder<IMedia>, MediaValueSetBuilder>();
builder.Services.AddUnique<IValueSetBuilder<IMember>, MemberValueSetBuilder>();
builder.Services.AddUnique<BackgroundIndexRebuilder>();
builder.Services.AddUnique<ExamineIndexRebuilder>();
builder.AddNotificationHandler<UmbracoApplicationStarting, ExamineNotificationHandler>();
builder.AddNotificationHandler<ContentCacheRefresherNotification, ExamineNotificationHandler>();
builder.AddNotificationHandler<ContentTypeCacheRefresherNotification, ExamineNotificationHandler>();
builder.AddNotificationHandler<MediaCacheRefresherNotification, ExamineNotificationHandler>();
builder.AddNotificationHandler<MemberCacheRefresherNotification, ExamineNotificationHandler>();
builder.AddNotificationHandler<LanguageCacheRefresherNotification, ExamineNotificationHandler>();
builder.AddNotificationHandler<ContentCacheRefresherNotification, ContentIndexingNotificationHandler>();
builder.AddNotificationHandler<ContentTypeCacheRefresherNotification, ContentTypeIndexingNotificationHandler>();
builder.AddNotificationHandler<MediaCacheRefresherNotification, MediaIndexingNotificationHandler>();
builder.AddNotificationHandler<MemberCacheRefresherNotification, MemberIndexingNotificationHandler>();
builder.AddNotificationHandler<LanguageCacheRefresherNotification, LanguageIndexingNotificationHandler>();
builder.AddNotificationHandler<UmbracoRequestBeginNotification, RebuildOnStartupHandler>();
return builder;
}

View File

@@ -19,10 +19,7 @@ namespace Umbraco.Cms.Infrastructure.DependencyInjection
* Create an implementation of IFileSystem and register it as the underlying filesystem for
* MediaFileSystem with the following extension on composition.
*
* composition.SetMediaFileSystem(factory => FactoryMethodToReturnYourImplementation())
*
* Alternatively you can just register an Implementation of IMediaFileSystem, however the
* extension above ensures that your IFileSystem implementation is wrapped by the "ShadowWrapper".
* builder.SetMediaFileSystem(factory => FactoryMethodToReturnYourImplementation())
*
* WHAT IS SHADOWING
* -----------------
@@ -37,23 +34,17 @@ namespace Umbraco.Cms.Infrastructure.DependencyInjection
internal static IUmbracoBuilder AddFileSystems(this IUmbracoBuilder builder)
{
// register FileSystems, which manages all filesystems
// it needs to be registered (not only the interface) because it provides additional
// functionality eg for scoping, and is injected in the scope provider - whereas the
// interface is really for end-users to get access to filesystems.
builder.Services.AddUnique(factory => factory.CreateInstance<FileSystems>(factory));
// register IFileSystems, which gives access too all filesystems
builder.Services.AddUnique<IFileSystems>(factory => factory.GetRequiredService<FileSystems>());
builder.Services.AddUnique<FileSystems>();
// register the scheme for media paths
builder.Services.AddUnique<IMediaPathScheme, UniqueMediaPathScheme>();
builder.SetMediaFileSystem(factory =>
{
var ioHelper = factory.GetRequiredService<IIOHelper>();
var hostingEnvironment = factory.GetRequiredService<IHostingEnvironment>();
var logger = factory.GetRequiredService<ILogger<PhysicalFileSystem>>();
var globalSettings = factory.GetRequiredService<IOptions<GlobalSettings>>().Value;
IIOHelper ioHelper = factory.GetRequiredService<IIOHelper>();
IHostingEnvironment hostingEnvironment = factory.GetRequiredService<IHostingEnvironment>();
ILogger<PhysicalFileSystem> logger = factory.GetRequiredService<ILogger<PhysicalFileSystem>>();
GlobalSettings globalSettings = factory.GetRequiredService<IOptions<GlobalSettings>>().Value;
var rootPath = hostingEnvironment.MapPathWebRoot(globalSettings.UmbracoMediaPath);
var rootUrl = hostingEnvironment.ToAbsolute(globalSettings.UmbracoMediaPath);

View File

@@ -1,5 +1,6 @@
using System;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Dictionary;
using Umbraco.Cms.Core.IO;
@@ -109,20 +110,48 @@ namespace Umbraco.Cms.Infrastructure.DependencyInjection
}
/// <summary>
/// Sets the underlying media filesystem.
/// Sets the filesystem used by the MediaFileManager
/// </summary>
/// <param name="builder">A builder.</param>
/// <param name="filesystemFactory">A filesystem factory.</param>
/// <remarks>
/// Using this helper will ensure that your IFileSystem implementation is wrapped by the ShadowWrapper
/// </remarks>
public static void SetMediaFileSystem(this IUmbracoBuilder builder, Func<IServiceProvider, IFileSystem> filesystemFactory)
=> builder.Services.AddUnique<IMediaFileSystem>(factory =>
/// <param name="filesystemFactory">Factory method to create an IFileSystem implementation used in the MediaFileManager</param>
public static void SetMediaFileSystem(this IUmbracoBuilder builder,
Func<IServiceProvider, IFileSystem> filesystemFactory) => builder.Services.AddUnique(
provider =>
{
var fileSystems = factory.GetRequiredService<FileSystems>();
return fileSystems.GetFileSystem<MediaFileSystem>(filesystemFactory(factory));
IFileSystem filesystem = filesystemFactory(provider);
// We need to use the Filesystems to create a shadow wrapper,
// because shadow wrapper requires the IsScoped delegate from the FileSystems.
// This is used by the scope provider when taking control of the filesystems.
FileSystems fileSystems = provider.GetRequiredService<FileSystems>();
IFileSystem shadow = fileSystems.CreateShadowWrapper(filesystem, "media");
return provider.CreateInstance<MediaFileManager>(shadow);
});
/// <summary>
/// Register FileSystems with a method to configure the <see cref="FileSystems"/>.
/// </summary>
/// <param name="builder">A builder.</param>
/// <param name="configure">Method that configures the <see cref="FileSystems"/>.</param>
/// <exception cref="ArgumentNullException">Throws exception if <paramref name="configure"/> is null.</exception>
/// <exception cref="InvalidOperationException">Throws exception if full path can't be resolved successfully.</exception>
public static void ConfigureFileSystems(this IUmbracoBuilder builder,
Action<IServiceProvider, FileSystems> configure)
{
if (configure == null)
{
throw new ArgumentNullException(nameof(configure));
}
builder.Services.AddUnique(
provider =>
{
FileSystems fileSystems = provider.CreateInstance<FileSystems>();
configure(provider, fileSystems);
return fileSystems;
});
}
/// <summary>
/// Sets the log viewer.
/// </summary>