Remove NotificationHandler lifetime hack

This commit is contained in:
Paul Johnson
2020-12-21 09:38:06 +00:00
parent 7600ae9e05
commit 822aa2897b
5 changed files with 55 additions and 91 deletions

View File

@@ -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<TNotification>), typeof(TNotificationHandler));
return builder;
}
/// <summary>
/// Registers a notification handler against the Umbraco service collection.
/// </summary>
/// <typeparam name="TNotification">The type of notification.</typeparam>
/// <typeparam name="TNotificationHandler">The type of notificiation handler.</typeparam>
/// <param name="builder">The Umbraco builder.</param>
/// <param name="factory">Factory method</param>
/// <returns>The <see cref="IUmbracoBuilder"/>.</returns>
public static IUmbracoBuilder AddNotificationHandler<TNotification, TNotificationHandler>(this IUmbracoBuilder builder, Func<IServiceProvider, TNotificationHandler> factory)
where TNotificationHandler : class, INotificationHandler<TNotification>
where TNotification : INotification
{
// Register the handler as transient. This ensures that anything can be injected into it.
builder.Services.AddTransient(typeof(INotificationHandler<TNotification>), factory);
return builder;
}
}
}

View File

@@ -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();
}
}
}
}

View File

@@ -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
{
/// <summary>
/// Starts monitoring AppPlugins directory during debug runs, to restart site when a plugin manifest changes.
/// </summary>
public sealed class AppPluginsManifestWatcherNotificationHandler : INotificationHandler<UmbracoApplicationStarting>
{
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;
}
}
}

View File

@@ -71,8 +71,7 @@ namespace Umbraco.Infrastructure.Runtime
builder.AddNotificationHandler<UmbracoApplicationStarting, EssentialDirectoryCreator>();
builder.Services.AddSingleton<ManifestWatcher>();
builder.AddNotificationHandler<UmbracoApplicationStarting, ManifestWatcher>(factory => factory.GetRequiredService<ManifestWatcher>());
builder.AddNotificationHandler<UmbracoApplicationStopping, ManifestWatcher>(factory => factory.GetRequiredService<ManifestWatcher>());
builder.AddNotificationHandler<UmbracoApplicationStarting, AppPluginsManifestWatcherNotificationHandler>();
// composers
builder

View File

@@ -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<UmbracoApplicationStarting>,
INotificationHandler<UmbracoApplicationStopping>
{
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<Core.Manifest.ManifestWatcher>(), _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;
}
}
}