Skip to content

Commit 1c096d3

Browse files
committed
Fix bug where DisposeCallback would not close to parent and child
1 parent 96a916f commit 1c096d3

File tree

3 files changed

+38
-7
lines changed

3 files changed

+38
-7
lines changed

VContainer/Assets/Tests/ContainerTest.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,31 @@ public void OnContainerDisposeCallback()
617617
Assert.That(resolvedJustBeforeDispose2, Is.Not.Null);
618618
}
619619

620+
[Test]
621+
public void OnContainerDisposeCallback_ParentChild()
622+
{
623+
var parentDisposeCalled = false;
624+
var childDisposeCalled = false;
625+
626+
var builder = new ContainerBuilder();
627+
builder.Register<NoDependencyServiceA>(Lifetime.Scoped);
628+
629+
builder.RegisterDisposeCallback(x => parentDisposeCalled = true);
630+
631+
var container = builder.Build();
632+
633+
var childContainer = container.CreateScope(childBuilder =>
634+
{
635+
childBuilder.Register<NoDependencyServiceB>(Lifetime.Scoped);
636+
childBuilder.RegisterDisposeCallback(x => childDisposeCalled = true);
637+
});
638+
639+
childContainer.Dispose();
640+
641+
Assert.That(childDisposeCalled, Is.True);
642+
Assert.That(parentDisposeCalled, Is.False);
643+
}
644+
620645
[Test]
621646
public void TryResolveTransient()
622647
{

VContainer/Assets/VContainer/Runtime/ContainerBuilderExtensions.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,15 @@ public static RegistrationBuilder RegisterFactory<TParam1, TParam2, TParam3, TPa
143143

144144
public static void RegisterDisposeCallback(this IContainerBuilder builder, Action<IObjectResolver> callback)
145145
{
146-
builder.Register(container => new BuilderCallbackDisposable(callback, container), Lifetime.Scoped);
147-
builder.RegisterBuildCallback(container => container.Resolve<IReadOnlyList<BuilderCallbackDisposable>>());
146+
if (!builder.Exists(typeof(BuilderCallbackDisposable)))
147+
{
148+
builder.Register<BuilderCallbackDisposable>(Lifetime.Singleton);
149+
}
150+
builder.RegisterBuildCallback(container =>
151+
{
152+
var disposable = container.Resolve<BuilderCallbackDisposable>();
153+
disposable.Disposing += callback;
154+
});
148155
}
149156

150157
[Obsolete("IObjectResolver is registered by default. This method does nothing.")]

VContainer/Assets/VContainer/Runtime/Internal/BuilderCallbackDisposable.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,19 @@
22

33
namespace VContainer.Internal
44
{
5-
readonly struct BuilderCallbackDisposable : IDisposable
5+
class BuilderCallbackDisposable : IDisposable
66
{
7-
readonly Action<IObjectResolver> callback;
7+
public event Action<IObjectResolver> Disposing;
88
readonly IObjectResolver container;
99

10-
public BuilderCallbackDisposable(Action<IObjectResolver> callback, IObjectResolver container)
10+
public BuilderCallbackDisposable(IObjectResolver container)
1111
{
12-
this.callback = callback;
1312
this.container = container;
1413
}
1514

1615
public void Dispose()
1716
{
18-
callback.Invoke(container);
17+
if (Disposing != null) Disposing.Invoke(container);
1918
}
2019
}
2120
}

0 commit comments

Comments
 (0)