diff --git a/src/ObjectPool/src/DefaultPooledObjectPolicy.cs b/src/ObjectPool/src/DefaultPooledObjectPolicy.cs index cc9ec1ee862a..fbf279f91361 100644 --- a/src/ObjectPool/src/DefaultPooledObjectPolicy.cs +++ b/src/ObjectPool/src/DefaultPooledObjectPolicy.cs @@ -18,8 +18,11 @@ public override T Create() /// public override bool Return(T obj) { - // DefaultObjectPool doesn't call 'Return' for the default policy. - // So take care adding any logic to this method, as it might require changes elsewhere. + if (obj is IResettable resettable) + { + return resettable.TryReset(); + } + return true; } } diff --git a/src/ObjectPool/src/IResettable.cs b/src/ObjectPool/src/IResettable.cs new file mode 100644 index 000000000000..3f6128da026c --- /dev/null +++ b/src/ObjectPool/src/IResettable.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.Extensions.ObjectPool; + +/// +/// Defines a method to reset an object to its initial state. +/// +public interface IResettable +{ + /// + /// Reset the object to a neutral state, semantically similar to when the object was first constructed. + /// + /// if the object was able to reset itself, otherwise . + /// + /// In general, this method is not expected to be thread-safe. + /// + bool TryReset(); +} diff --git a/src/ObjectPool/src/PublicAPI.Unshipped.txt b/src/ObjectPool/src/PublicAPI.Unshipped.txt index 7dc5c58110bf..66b783063ba8 100644 --- a/src/ObjectPool/src/PublicAPI.Unshipped.txt +++ b/src/ObjectPool/src/PublicAPI.Unshipped.txt @@ -1 +1,3 @@ #nullable enable +Microsoft.Extensions.ObjectPool.IResettable +Microsoft.Extensions.ObjectPool.IResettable.TryReset() -> bool diff --git a/src/ObjectPool/test/DefaultObjectPoolTest.cs b/src/ObjectPool/test/DefaultObjectPoolTest.cs index cdaed4e78ea5..0ebce3763e3e 100644 --- a/src/ObjectPool/test/DefaultObjectPoolTest.cs +++ b/src/ObjectPool/test/DefaultObjectPoolTest.cs @@ -69,6 +69,34 @@ public void DefaultObjectPool_Return_RejectedByPolicy() Assert.NotSame(list1, list2); } + [Fact] + public static void DefaultObjectPool_Honors_IResettable() + { + var p = new DefaultObjectPool(new DefaultPooledObjectPolicy()); + var r = new Resettable(); + + r.ResetReturnValue = false; + p.Return(r); + Assert.Equal(1, r.ResetCallCount); + Assert.NotSame(r, p.Get()); + + r.ResetReturnValue = true; + p.Return(r); + Assert.Equal(2, r.ResetCallCount); + Assert.Same(r, p.Get()); + } + + private sealed class Resettable : IResettable + { + public int ResetCallCount { get; set; } + public bool ResetReturnValue { get; set; } + public bool TryReset() + { + ResetCallCount++; + return ResetReturnValue; + } + } + private class ListPolicy : IPooledObjectPolicy> { public List Create()