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()