diff --git a/src/DI.Specification.Tests/DependencyInjectionSpecificationTests.cs b/src/DI.Specification.Tests/DependencyInjectionSpecificationTests.cs index 4bfa9d3f..ac099ca3 100644 --- a/src/DI.Specification.Tests/DependencyInjectionSpecificationTests.cs +++ b/src/DI.Specification.Tests/DependencyInjectionSpecificationTests.cs @@ -742,5 +742,55 @@ public void ResolvesDifferentInstancesForServiceWhenResolvingEnumerable(Type ser Assert.Equal(service, enumerable[2]); } } + + [Fact] + public void ServicesAreDisposedOnlyOnce_SingletonInRootScope() + { + // Arrange + var collection = new TestServiceCollection(); + collection.AddSingleton(); + collection.AddSingleton(sp => sp.GetService()); + var provider = CreateServiceProvider(collection); + + // Act & Assert + var service = provider.GetService(); + var service2 = provider.GetService(); + + (provider as IDisposable).Dispose(); + } + + [Fact] + public void ServicesAreDisposedOnlyOnce_ScopedInScope() + { + // Arrange + var collection = new TestServiceCollection(); + collection.AddScoped(); + collection.AddScoped(sp => sp.GetService()); + var provider = CreateServiceProvider(collection); + + // Act & Assert + using (var scope = provider.CreateScope()) + { + var service1 = scope.ServiceProvider.GetService(); + var service2 = scope.ServiceProvider.GetService(); + } + } + + [Fact] + public void ServicesAreDisposedOnlyOnce_TransientInScope() + { + // Arrange + var collection = new TestServiceCollection(); + collection.AddTransient(); + collection.AddTransient(sp => sp.GetService()); + var provider = CreateServiceProvider(collection); + + // Act & Assert + using (var scope = provider.CreateScope()) + { + var service1 = scope.ServiceProvider.GetService(); + var service2 = scope.ServiceProvider.GetService(); + } + } } } diff --git a/src/DI/ServiceLookup/ServiceProviderEngineScope.cs b/src/DI/ServiceLookup/ServiceProviderEngineScope.cs index 5b876cd2..f4b51bb9 100644 --- a/src/DI/ServiceLookup/ServiceProviderEngineScope.cs +++ b/src/DI/ServiceLookup/ServiceProviderEngineScope.cs @@ -48,10 +48,12 @@ public void Dispose() _disposed = true; if (_disposables != null) { + var disposed = new HashSet(); for (var i = _disposables.Count - 1; i >= 0; i--) { var disposable = _disposables[i]; - disposable.Dispose(); + if (disposed.Add(disposable)) + disposable.Dispose(); } _disposables.Clear();