Create scoped notification publishing - particularly for "ed" notifications that must run after the current scope has completed
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.Events;
|
||||
using Umbraco.Cms.Infrastructure.Persistence;
|
||||
@@ -30,6 +30,11 @@ namespace Umbraco.Cms.Core.Scoping
|
||||
/// </summary>
|
||||
IEventDispatcher Events { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the scope notification publisher
|
||||
/// </summary>
|
||||
IScopedNotificationPublisher Notifications { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the repositories cache mode.
|
||||
/// </summary>
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace Umbraco.Cms.Core.Scoping
|
||||
private readonly ScopeProvider _scopeProvider;
|
||||
private readonly CoreDebugSettings _coreDebugSettings;
|
||||
private readonly IMediaFileSystem _mediaFileSystem;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly ILogger<Scope> _logger;
|
||||
|
||||
private readonly IsolationLevel _isolationLevel;
|
||||
@@ -35,12 +36,15 @@ namespace Umbraco.Cms.Core.Scoping
|
||||
private EventMessages _messages;
|
||||
private ICompletable _fscope;
|
||||
private IEventDispatcher _eventDispatcher;
|
||||
// eventually this may need to be injectable - for now we'll create it explicitly and let future needs determine if it should be injectable
|
||||
private IScopedNotificationPublisher _notificationPublisher;
|
||||
|
||||
// initializes a new scope
|
||||
private Scope(
|
||||
ScopeProvider scopeProvider,
|
||||
CoreDebugSettings coreDebugSettings,
|
||||
IMediaFileSystem mediaFileSystem,
|
||||
IEventAggregator eventAggregator,
|
||||
ILogger<Scope> logger,
|
||||
FileSystems fileSystems,
|
||||
Scope parent,
|
||||
@@ -56,6 +60,7 @@ namespace Umbraco.Cms.Core.Scoping
|
||||
_scopeProvider = scopeProvider;
|
||||
_coreDebugSettings = coreDebugSettings;
|
||||
_mediaFileSystem = mediaFileSystem;
|
||||
_eventAggregator = eventAggregator;
|
||||
_logger = logger;
|
||||
|
||||
Context = scopeContext;
|
||||
@@ -69,6 +74,7 @@ namespace Umbraco.Cms.Core.Scoping
|
||||
|
||||
Detachable = detachable;
|
||||
|
||||
|
||||
#if DEBUG_SCOPES
|
||||
_scopeProvider.RegisterScope(this);
|
||||
Console.WriteLine("create " + InstanceId.ToString("N").Substring(0, 8));
|
||||
@@ -124,6 +130,7 @@ namespace Umbraco.Cms.Core.Scoping
|
||||
ScopeProvider scopeProvider,
|
||||
CoreDebugSettings coreDebugSettings,
|
||||
IMediaFileSystem mediaFileSystem,
|
||||
IEventAggregator eventAggregator,
|
||||
ILogger<Scope> logger,
|
||||
FileSystems fileSystems,
|
||||
bool detachable,
|
||||
@@ -134,7 +141,7 @@ namespace Umbraco.Cms.Core.Scoping
|
||||
bool? scopeFileSystems = null,
|
||||
bool callContext = false,
|
||||
bool autoComplete = false)
|
||||
: this(scopeProvider, coreDebugSettings, mediaFileSystem, logger, fileSystems, null, scopeContext, detachable, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete)
|
||||
: this(scopeProvider, coreDebugSettings, mediaFileSystem, eventAggregator, logger, fileSystems, null, scopeContext, detachable, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete)
|
||||
{ }
|
||||
|
||||
// initializes a new scope in a nested scopes chain, with its parent
|
||||
@@ -142,6 +149,7 @@ namespace Umbraco.Cms.Core.Scoping
|
||||
ScopeProvider scopeProvider,
|
||||
CoreDebugSettings coreDebugSettings,
|
||||
IMediaFileSystem mediaFileSystem,
|
||||
IEventAggregator eventAggregator,
|
||||
ILogger<Scope> logger,
|
||||
FileSystems fileSystems,
|
||||
Scope parent,
|
||||
@@ -151,7 +159,7 @@ namespace Umbraco.Cms.Core.Scoping
|
||||
bool? scopeFileSystems = null,
|
||||
bool callContext = false,
|
||||
bool autoComplete = false)
|
||||
: this(scopeProvider, coreDebugSettings, mediaFileSystem, logger, fileSystems, parent, null, false, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete)
|
||||
: this(scopeProvider, coreDebugSettings, mediaFileSystem, eventAggregator, logger, fileSystems, parent, null, false, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete)
|
||||
{ }
|
||||
|
||||
public Guid InstanceId { get; } = Guid.NewGuid();
|
||||
@@ -314,6 +322,16 @@ namespace Umbraco.Cms.Core.Scoping
|
||||
}
|
||||
}
|
||||
|
||||
public IScopedNotificationPublisher Notifications
|
||||
{
|
||||
get
|
||||
{
|
||||
EnsureNotDisposed();
|
||||
if (ParentScope != null) return ParentScope.Notifications;
|
||||
return _notificationPublisher ?? (_notificationPublisher = new ScopedNotificationPublisher(_eventAggregator));
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Complete()
|
||||
{
|
||||
@@ -453,7 +471,10 @@ namespace Umbraco.Cms.Core.Scoping
|
||||
{
|
||||
// deal with events
|
||||
if (onException == false)
|
||||
{
|
||||
_eventDispatcher?.ScopeExit(completed);
|
||||
_notificationPublisher?.ScopeExit(completed);
|
||||
}
|
||||
}, () =>
|
||||
{
|
||||
// if *we* created it, then get rid of it
|
||||
|
||||
@@ -26,8 +26,9 @@ namespace Umbraco.Cms.Core.Scoping
|
||||
private readonly FileSystems _fileSystems;
|
||||
private readonly CoreDebugSettings _coreDebugSettings;
|
||||
private readonly IMediaFileSystem _mediaFileSystem;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
|
||||
public ScopeProvider(IUmbracoDatabaseFactory databaseFactory, FileSystems fileSystems, IOptions<CoreDebugSettings> coreDebugSettings, IMediaFileSystem mediaFileSystem, ILogger<ScopeProvider> logger, ILoggerFactory loggerFactory, IRequestCache requestCache)
|
||||
public ScopeProvider(IUmbracoDatabaseFactory databaseFactory, FileSystems fileSystems, IOptions<CoreDebugSettings> coreDebugSettings, IMediaFileSystem mediaFileSystem, ILogger<ScopeProvider> logger, ILoggerFactory loggerFactory, IRequestCache requestCache, IEventAggregator eventAggregator)
|
||||
{
|
||||
DatabaseFactory = databaseFactory;
|
||||
_fileSystems = fileSystems;
|
||||
@@ -36,6 +37,7 @@ namespace Umbraco.Cms.Core.Scoping
|
||||
_logger = logger;
|
||||
_loggerFactory = loggerFactory;
|
||||
_requestCache = requestCache;
|
||||
_eventAggregator = eventAggregator;
|
||||
// take control of the FileSystems
|
||||
_fileSystems.IsScoped = () => AmbientScope != null && AmbientScope.ScopedFileSystems;
|
||||
|
||||
@@ -253,7 +255,7 @@ namespace Umbraco.Cms.Core.Scoping
|
||||
IEventDispatcher eventDispatcher = null,
|
||||
bool? scopeFileSystems = null)
|
||||
{
|
||||
return new Scope(this, _coreDebugSettings, _mediaFileSystem, _loggerFactory.CreateLogger<Scope>(), _fileSystems, true, null, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems);
|
||||
return new Scope(this, _coreDebugSettings, _mediaFileSystem, _eventAggregator, _loggerFactory.CreateLogger<Scope>(), _fileSystems, true, null, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -309,13 +311,13 @@ namespace Umbraco.Cms.Core.Scoping
|
||||
{
|
||||
var ambientContext = AmbientContext;
|
||||
var newContext = ambientContext == null ? new ScopeContext() : null;
|
||||
var scope = new Scope(this, _coreDebugSettings, _mediaFileSystem, _loggerFactory.CreateLogger<Scope>(), _fileSystems, false, newContext, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete);
|
||||
var scope = new Scope(this, _coreDebugSettings, _mediaFileSystem, _eventAggregator, _loggerFactory.CreateLogger<Scope>(), _fileSystems, false, newContext, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete);
|
||||
// assign only if scope creation did not throw!
|
||||
SetAmbient(scope, newContext ?? ambientContext);
|
||||
return scope;
|
||||
}
|
||||
|
||||
var nested = new Scope(this, _coreDebugSettings, _mediaFileSystem, _loggerFactory.CreateLogger<Scope>(), _fileSystems, ambientScope, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete);
|
||||
var nested = new Scope(this, _coreDebugSettings, _mediaFileSystem, _eventAggregator, _loggerFactory.CreateLogger<Scope>(), _fileSystems, ambientScope, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete);
|
||||
SetAmbient(nested, AmbientContext);
|
||||
return nested;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user