diff --git a/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Events.cs b/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Events.cs index a4ae2874e3..a21ae74976 100644 --- a/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Events.cs +++ b/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Events.cs @@ -1,7 +1,6 @@ // Copyright (c) Umbraco. // See LICENSE for more details. -using System; using Microsoft.Extensions.DependencyInjection; using Umbraco.Core.Events; @@ -27,22 +26,5 @@ namespace Umbraco.Core.DependencyInjection builder.Services.AddTransient(typeof(INotificationHandler), typeof(TNotificationHandler)); return builder; } - - /// - /// Registers a notification handler against the Umbraco service collection. - /// - /// The type of notification. - /// The type of notificiation handler. - /// The Umbraco builder. - /// Factory method - /// The . - public static IUmbracoBuilder AddNotificationHandler(this IUmbracoBuilder builder, Func factory) - where TNotificationHandler : class, INotificationHandler - where TNotification : INotification - { - // Register the handler as transient. This ensures that anything can be injected into it. - builder.Services.AddTransient(typeof(INotificationHandler), factory); - return builder; - } } } diff --git a/src/Umbraco.Core/Manifest/ManifestWatcher.cs b/src/Umbraco.Core/Manifest/ManifestWatcher.cs index 6bd893d298..16e961652f 100644 --- a/src/Umbraco.Core/Manifest/ManifestWatcher.cs +++ b/src/Umbraco.Core/Manifest/ManifestWatcher.cs @@ -1,14 +1,13 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; using Microsoft.Extensions.Logging; -using Umbraco.Core.Hosting; using Umbraco.Net; namespace Umbraco.Core.Manifest { - public class ManifestWatcher : DisposableObjectSlim + public class ManifestWatcher : IDisposable { private static readonly object Locker = new object(); private static volatile bool _isRestarting; @@ -48,7 +47,10 @@ namespace Umbraco.Core.Manifest private void FswChanged(object sender, FileSystemEventArgs e) { - if (e.Name.InvariantContains("package.manifest") == false) return; + if (!e.Name.InvariantContains("package.manifest")) + { + return; + } // ensure the app is not restarted multiple times for multiple // savings during the same app domain execution - restart once @@ -59,14 +61,15 @@ namespace Umbraco.Core.Manifest _isRestarting = true; _logger.LogInformation("Manifest has changed, app pool is restarting ({Path})", e.FullPath); _umbracoApplicationLifetime.Restart(); - Dispose(); // uh? if the app restarts then this should be disposed anyways? } } - protected override void DisposeResources() + public void Dispose() { foreach (var fw in _fws) + { fw.Dispose(); + } } } } diff --git a/src/Umbraco.Infrastructure/Runtime/AppPluginsManifestWatcherNotificationHandler.cs b/src/Umbraco.Infrastructure/Runtime/AppPluginsManifestWatcherNotificationHandler.cs new file mode 100644 index 0000000000..b67f41136a --- /dev/null +++ b/src/Umbraco.Infrastructure/Runtime/AppPluginsManifestWatcherNotificationHandler.cs @@ -0,0 +1,45 @@ +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using Umbraco.Core; +using Umbraco.Core.Events; +using Umbraco.Core.Hosting; +using Umbraco.Core.Manifest; + +namespace Umbraco.Infrastructure.Runtime +{ + /// + /// Starts monitoring AppPlugins directory during debug runs, to restart site when a plugin manifest changes. + /// + public sealed class AppPluginsManifestWatcherNotificationHandler : INotificationHandler + { + private readonly ManifestWatcher _manifestWatcher; + private readonly IHostingEnvironment _hostingEnvironment; + + public AppPluginsManifestWatcherNotificationHandler(ManifestWatcher manifestWatcher, IHostingEnvironment hostingEnvironment) + { + _manifestWatcher = manifestWatcher ?? throw new ArgumentNullException(nameof(manifestWatcher)); + _hostingEnvironment = hostingEnvironment ?? throw new ArgumentNullException(nameof(hostingEnvironment)); + } + + public Task HandleAsync(UmbracoApplicationStarting notification, CancellationToken cancellationToken) + { + if (!_hostingEnvironment.IsDebugMode) + { + return Task.CompletedTask; + } + + var appPlugins = _hostingEnvironment.MapPathContentRoot(Constants.SystemDirectories.AppPlugins); + + if (!Directory.Exists(appPlugins)) + { + return Task.CompletedTask; + } + + _manifestWatcher.Start(Directory.GetDirectories(appPlugins)); + + return Task.CompletedTask; + } + } +} diff --git a/src/Umbraco.Infrastructure/Runtime/CoreInitialServices.cs b/src/Umbraco.Infrastructure/Runtime/CoreInitialServices.cs index 0fa3250522..32f5e6bf36 100644 --- a/src/Umbraco.Infrastructure/Runtime/CoreInitialServices.cs +++ b/src/Umbraco.Infrastructure/Runtime/CoreInitialServices.cs @@ -71,8 +71,7 @@ namespace Umbraco.Infrastructure.Runtime builder.AddNotificationHandler(); builder.Services.AddSingleton(); - builder.AddNotificationHandler(factory => factory.GetRequiredService()); - builder.AddNotificationHandler(factory => factory.GetRequiredService()); + builder.AddNotificationHandler(); // composers builder diff --git a/src/Umbraco.Infrastructure/Runtime/ManifestWatcher.cs b/src/Umbraco.Infrastructure/Runtime/ManifestWatcher.cs deleted file mode 100644 index 358dfb2ed5..0000000000 --- a/src/Umbraco.Infrastructure/Runtime/ManifestWatcher.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System.IO; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.Extensions.Logging; -using Umbraco.Core; -using Umbraco.Core.Events; -using Umbraco.Core.Hosting; -using Umbraco.Net; - -namespace Umbraco.Infrastructure.Runtime -{ - public sealed class ManifestWatcher : - INotificationHandler, - INotificationHandler - { - private readonly IHostingEnvironment _hosting; - private readonly ILoggerFactory _loggerFactory; - private readonly IHostingEnvironment _hostingEnvironment; - private readonly IUmbracoApplicationLifetime _umbracoApplicationLifetime; - - // if configured and in debug mode, a ManifestWatcher watches App_Plugins folders for - // package.manifest chances and restarts the application on any change - private Core.Manifest.ManifestWatcher _mw; - - public ManifestWatcher(IHostingEnvironment hosting, ILoggerFactory loggerFactory, IHostingEnvironment hostingEnvironment, IUmbracoApplicationLifetime umbracoApplicationLifetime) - { - _hosting = hosting; - _loggerFactory = loggerFactory; - _hostingEnvironment = hostingEnvironment; - _umbracoApplicationLifetime = umbracoApplicationLifetime; - } - - public Task HandleAsync(UmbracoApplicationStarting notification, CancellationToken cancellationToken) - { - if (_hosting.IsDebugMode == false) - { - return Task.CompletedTask; - } - - var appPlugins = _hostingEnvironment.MapPathContentRoot(Constants.SystemDirectories.AppPlugins); - if (Directory.Exists(appPlugins) == false) - { - return Task.CompletedTask; - } - - _mw = new Core.Manifest.ManifestWatcher(_loggerFactory.CreateLogger(), _umbracoApplicationLifetime); - _mw.Start(Directory.GetDirectories(appPlugins)); - - return Task.CompletedTask; - } - - public Task HandleAsync(UmbracoApplicationStopping notification, CancellationToken cancellationToken) - { - if (_mw == null) - { - return Task.CompletedTask; - } - - _mw.Dispose(); - _mw = null; - - return Task.CompletedTask; - } - } -}