/// <summary> /// Returns true if the shell context should be disposed consequently to this scope being released. /// </summary> private bool ScopeReleased() { // A disabled shell still in use is released by its last scope. if (_shellContext.Settings.State == TenantState.Disabled) { if (Interlocked.CompareExchange(ref _shellContext._refCount, 1, 1) == 1) { _shellContext.Release(); } } // If the context is still being released, it will be disposed if the ref counter is equal to 0. // To prevent this while executing the terminating events, the ref counter is not decremented here. if (_shellContext._released && Interlocked.CompareExchange(ref _shellContext._refCount, 1, 1) == 1) { var tenantEvents = _serviceScope.ServiceProvider.GetServices <IModularTenantEvents>(); foreach (var tenantEvent in tenantEvents) { tenantEvent.TerminatingAsync().GetAwaiter().GetResult(); } foreach (var tenantEvent in tenantEvents.Reverse()) { tenantEvent.TerminatedAsync().GetAwaiter().GetResult(); } return(true); } return(false); }
/// <summary> /// Registers the specified shellContext as a dependency such that they are also reloaded when the current shell context is reloaded. /// </summary> public void AddDependentShell(ShellContext shellContext) { // If the dependent is released, nothing to do. if (shellContext.Released) { return; } // If the dependency is already released. if (_released) { // The dependent is released immediately. shellContext.Release(); return; } lock (_synLock) { if (_dependents == null) { _dependents = new List <WeakReference <ShellContext> >(); } // Remove any previous instance that represent the same tenant in case it has been released (restarted). _dependents.RemoveAll(x => !x.TryGetTarget(out var shell) || shell.Settings.Name == shellContext.Settings.Name); _dependents.Add(new WeakReference <ShellContext>(shellContext)); } }