diff --git a/src/Pure.DI.Core/Components/Api.g.cs b/src/Pure.DI.Core/Components/Api.g.cs index 718d7949..5ef16efb 100644 --- a/src/Pure.DI.Core/Components/Api.g.cs +++ b/src/Pure.DI.Core/Components/Api.g.cs @@ -1100,11 +1100,12 @@ public interface IOwned : global::System.IDisposable /// [global::System.Diagnostics.DebuggerDisplay("{_disposables.Count} item(s)")] [global::System.Diagnostics.DebuggerTypeProxy(typeof(global::Pure.DI.Owned.DebugView))] - internal partial class Owned : global::Pure.DI.IOwned + internal partial struct Owned : global::Pure.DI.IOwned { - private global::System.Collections.Generic.List _disposables - = new global::System.Collections.Generic.List(); - + private volatile object _lockObject; + private int _count; + private global::System.IDisposable[] _disposables; + /// /// Adds a disposable instance. /// @@ -1117,9 +1118,29 @@ public void Add(global::System.IDisposable disposable) return; } - lock (_disposables) + if (_lockObject == null) { - _disposables.Add(disposable); + while (global::System.Threading.Interlocked.CompareExchange(ref _lockObject, new object(), null) == null) ; + } + + lock (_lockObject) + { + if (_count == 0) + { + _disposables = new global::System.IDisposable[8]; + } + else + { + var size = _disposables.Length; + if (size == _count) + { + var disposables = new global::System.IDisposable[size << 1]; + global::System.Array.Copy(_disposables, disposables, size); + _disposables = disposables; + } + } + + _disposables[_count++] = disposable; } } @@ -1127,16 +1148,25 @@ public void Add(global::System.IDisposable disposable) [global::System.Runtime.CompilerServices.MethodImpl((global::System.Runtime.CompilerServices.MethodImplOptions)512)] public void Dispose() { - global::System.Collections.Generic.List disposables; - lock (_disposables) + if (_lockObject == null) + { + return; + } + + global::System.IDisposable[] disposables; + int count; + lock (_lockObject) { - disposables = _disposables; - _disposables = new global::System.Collections.Generic.List(); + disposables = new global::System.IDisposable[_count]; + global::System.Array.Copy(_disposables, disposables, _count); + count = _count; + _count = 0; + _disposables = null; } - disposables.Reverse(); - foreach (var disposable in disposables) + for (int i = count - 1; i >= 0; i--) { + var disposable = disposables[i]; try { disposable.Dispose(); @@ -1169,7 +1199,16 @@ public DebugView(global::Pure.DI.Owned owned) [global::System.Diagnostics.DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] public global::System.Collections.Generic.List Owns { - get { return _owned._disposables; } + get + { + global::System.Collections.Generic.List list = new global::System.Collections.Generic.List(_owned._count); + for (int i = 0; i < _owned._count; i++) + { + list.Add(_owned._disposables[i]); + } + + return list; + } } } } diff --git a/tests/Pure.DI.IntegrationTests/AccumulatorTests.cs b/tests/Pure.DI.IntegrationTests/AccumulatorTests.cs index 8cdd227c..36bff90a 100644 --- a/tests/Pure.DI.IntegrationTests/AccumulatorTests.cs +++ b/tests/Pure.DI.IntegrationTests/AccumulatorTests.cs @@ -94,7 +94,7 @@ public static void Main() // Then result.Success.ShouldBeTrue(result); - result.StdOut.ShouldBe(ImmutableArray.Create("3", "Sample.XyzDependency", "Sample.AbcDependency", "Sample.Service")); + result.StdOut.ShouldBe(["3", "Sample.XyzDependency", "Sample.AbcDependency", "Sample.Service"]); } [Fact] @@ -215,7 +215,7 @@ public static void Main() // Then result.Success.ShouldBeTrue(result); - result.StdOut.ShouldBe(ImmutableArray.Create("Value is not created.", "Sample.ShroedingersCat", "(Sample.ShroedingersCat, Sample.Accumulator)", "CardboardBox created", "(Sample.Program, Sample.Accumulator)", "[Sample.ShroedingersCat]", "Sample.Program", "(Sample.Program, Sample.Accumulator)", "Program created")); + result.StdOut.ShouldBe(["Value is not created.", "Sample.ShroedingersCat", "(Sample.ShroedingersCat, Sample.Accumulator)", "CardboardBox created", "(Sample.Program, Sample.Accumulator)", "[Sample.ShroedingersCat]", "Sample.Program", "(Sample.Program, Sample.Accumulator)", "Program created"]); } [Fact] @@ -279,7 +279,7 @@ public static void Main() // Then result.Success.ShouldBeTrue(result); - result.StdOut.ShouldBe(ImmutableArray.Create("Sample.Service", "(Sample.Service, Sample.MyAccumulator)")); + result.StdOut.ShouldBe(["Sample.Service", "(Sample.Service, Sample.MyAccumulator)"]); } [Fact] @@ -350,7 +350,7 @@ public static void Main() // Then result.Success.ShouldBeTrue(result); - result.StdOut.ShouldBe(ImmutableArray.Create("True", "False", "True")); + result.StdOut.ShouldBe(["True", "False", "True"]); } [Fact] @@ -421,7 +421,7 @@ public static void Main() // Then result.Success.ShouldBeTrue(result); - result.StdOut.ShouldBe(ImmutableArray.Create("True", "False", "True")); + result.StdOut.ShouldBe(["True", "False", "True"]); } [Fact] @@ -492,7 +492,7 @@ public static void Main() // Then result.Success.ShouldBeTrue(result); - result.StdOut.ShouldBe(ImmutableArray.Create("True", "False", "True")); + result.StdOut.ShouldBe(["True", "False", "True"]); } #if ROSLYN4_8_OR_GREATER