diff --git a/Assets/Reflex.EditModeTests/DisposeTests.cs b/Assets/Reflex.EditModeTests/DisposeTests.cs index baf731c1..635deb92 100644 --- a/Assets/Reflex.EditModeTests/DisposeTests.cs +++ b/Assets/Reflex.EditModeTests/DisposeTests.cs @@ -87,5 +87,40 @@ Service Factory(Container container) container.Dispose(); service.Disposed.Should().Be(1); } + + [Test] + public void OnDisposing_ShouldFire_BeforeRegisteredDisposablesAreDisposed() + { + var service = new Service(); + var observedDisposedAtEvent = -1; + + var container = new ContainerBuilder() + .RegisterValue(service) + .Build(); + + container.OnDisposing += _ => observedDisposedAtEvent = service.Disposed; + container.Dispose(); + + observedDisposedAtEvent.Should().Be(0); + service.Disposed.Should().Be(1); + } + + [Test] + public void OnDisposing_ShouldFire_BeforeChildContainersAreDisposed() + { + var parentEventOrder = -1; + var childDisposeOrder = -1; + var counter = 0; + + var parent = new ContainerBuilder().Build(); + var child = parent.Scope(); + child.OnDisposing += _ => childDisposeOrder = ++counter; + parent.OnDisposing += _ => parentEventOrder = ++counter; + + parent.Dispose(); + + parentEventOrder.Should().Be(1); + childDisposeOrder.Should().Be(2); + } } -} \ No newline at end of file +} diff --git a/Assets/Reflex/Core/Container.cs b/Assets/Reflex/Core/Container.cs index 1d94c41c..bf2a2f51 100644 --- a/Assets/Reflex/Core/Container.cs +++ b/Assets/Reflex/Core/Container.cs @@ -15,6 +15,7 @@ public sealed class Container : IDisposable public static Container RootContainer { get; internal set; } public string Name { get; } public Container Parent { get; } + public event Action OnDisposing; internal List Children { get; } = new(); internal Dictionary> ResolversByContract { get; } internal DisposableCollection Disposables { get; } @@ -52,6 +53,8 @@ public bool HasBinding(Type type) public void Dispose() { + OnDisposing?.Invoke(this); + foreach (var child in Children.Reversed()) { child.Dispose();