diff --git a/BitFaster.Caching/Atomic/AtomicFactoryAsyncCache.cs b/BitFaster.Caching/Atomic/AtomicFactoryAsyncCache.cs
index d632bdb2..b3ab6791 100644
--- a/BitFaster.Caching/Atomic/AtomicFactoryAsyncCache.cs
+++ b/BitFaster.Caching/Atomic/AtomicFactoryAsyncCache.cs
@@ -2,6 +2,7 @@
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;
namespace BitFaster.Caching.Atomic
@@ -11,6 +12,7 @@ namespace BitFaster.Caching.Atomic
///
/// The type of keys in the cache.
/// The type of values in the cache.
+ [DebuggerTypeProxy(typeof(AtomicFactoryAsyncCache<,>.AsyncCacheDebugView))]
[DebuggerDisplay("Count = {Count}")]
public sealed class AtomicFactoryAsyncCache : IAsyncCache
{
@@ -133,5 +135,33 @@ protected override ItemUpdatedEventArgs TranslateOnUpdated(ItemUpdatedEven
return new ItemUpdatedEventArgs(inner.Key, inner.OldValue.ValueIfCreated, inner.NewValue.ValueIfCreated);
}
}
+
+ [ExcludeFromCodeCoverage]
+ internal class AsyncCacheDebugView
+ {
+ private readonly IAsyncCache cache;
+
+ public AsyncCacheDebugView(IAsyncCache cache)
+ {
+ this.cache = cache;
+ }
+
+ public KeyValuePair[] Items
+ {
+ get
+ {
+ var items = new KeyValuePair[cache.Count];
+
+ int index = 0;
+ foreach (var kvp in cache)
+ {
+ items[index++] = kvp;
+ }
+ return items;
+ }
+ }
+
+ public ICacheMetrics Metrics => cache.Metrics.Value;
+ }
}
}
diff --git a/BitFaster.Caching/Atomic/AtomicFactoryCache.cs b/BitFaster.Caching/Atomic/AtomicFactoryCache.cs
index a184b86c..e503383f 100644
--- a/BitFaster.Caching/Atomic/AtomicFactoryCache.cs
+++ b/BitFaster.Caching/Atomic/AtomicFactoryCache.cs
@@ -10,6 +10,7 @@ namespace BitFaster.Caching.Atomic
///
/// The type of keys in the cache.
/// The type of values in the cache.
+ [DebuggerTypeProxy(typeof(CacheDebugView<,>))]
[DebuggerDisplay("Count = {Count}")]
public sealed class AtomicFactoryCache : ICache
{
diff --git a/BitFaster.Caching/Atomic/AtomicFactoryScopedAsyncCache.cs b/BitFaster.Caching/Atomic/AtomicFactoryScopedAsyncCache.cs
index 15e54b39..9fd429d0 100644
--- a/BitFaster.Caching/Atomic/AtomicFactoryScopedAsyncCache.cs
+++ b/BitFaster.Caching/Atomic/AtomicFactoryScopedAsyncCache.cs
@@ -12,6 +12,7 @@ namespace BitFaster.Caching.Atomic
///
/// The type of keys in the cache.
/// The type of values in the cache.
+ [DebuggerTypeProxy(typeof(ScopedAsyncCacheDebugView<,>))]
[DebuggerDisplay("Count = {Count}")]
public sealed class AtomicFactoryScopedAsyncCache : IScopedAsyncCache where V : IDisposable
{
diff --git a/BitFaster.Caching/Atomic/AtomicFactoryScopedCache.cs b/BitFaster.Caching/Atomic/AtomicFactoryScopedCache.cs
index ec32ac5f..d8ba13de 100644
--- a/BitFaster.Caching/Atomic/AtomicFactoryScopedCache.cs
+++ b/BitFaster.Caching/Atomic/AtomicFactoryScopedCache.cs
@@ -11,6 +11,7 @@ namespace BitFaster.Caching.Atomic
///
/// The type of keys in the cache.
/// The type of values in the cache.
+ [DebuggerTypeProxy(typeof(ScopedCacheDebugView<,>))]
[DebuggerDisplay("Count = {Count}")]
public sealed class AtomicFactoryScopedCache : IScopedCache where V : IDisposable
{
diff --git a/BitFaster.Caching/Lru/LruDebugView.cs b/BitFaster.Caching/CacheDebugView.cs
similarity index 82%
rename from BitFaster.Caching/Lru/LruDebugView.cs
rename to BitFaster.Caching/CacheDebugView.cs
index 00f2b140..7f1538db 100644
--- a/BitFaster.Caching/Lru/LruDebugView.cs
+++ b/BitFaster.Caching/CacheDebugView.cs
@@ -1,16 +1,15 @@
-using System;
-using System.Collections;
+
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
-namespace BitFaster.Caching.Lru
+namespace BitFaster.Caching
{
[ExcludeFromCodeCoverage]
- internal class LruDebugView
+ internal class CacheDebugView
{
private readonly ICache cache;
- public LruDebugView(ICache cache)
+ public CacheDebugView(ICache cache)
{
if (cache is null)
{
diff --git a/BitFaster.Caching/Lru/ConcurrentLru.cs b/BitFaster.Caching/Lru/ConcurrentLru.cs
index 13313707..45e3f0b5 100644
--- a/BitFaster.Caching/Lru/ConcurrentLru.cs
+++ b/BitFaster.Caching/Lru/ConcurrentLru.cs
@@ -4,7 +4,7 @@
namespace BitFaster.Caching.Lru
{
///
- [DebuggerTypeProxy(typeof(LruDebugView<,>))]
+ [DebuggerTypeProxy(typeof(CacheDebugView<,>))]
[DebuggerDisplay("Count = {Count}/{Capacity}")]
public sealed class ConcurrentLru : ConcurrentLruCore, LruPolicy, TelemetryPolicy>
{
diff --git a/BitFaster.Caching/Lru/ConcurrentTLru.cs b/BitFaster.Caching/Lru/ConcurrentTLru.cs
index 829bdf6e..faba1d2b 100644
--- a/BitFaster.Caching/Lru/ConcurrentTLru.cs
+++ b/BitFaster.Caching/Lru/ConcurrentTLru.cs
@@ -5,7 +5,7 @@
namespace BitFaster.Caching.Lru
{
///
- [DebuggerTypeProxy(typeof(LruDebugView<,>))]
+ [DebuggerTypeProxy(typeof(CacheDebugView<,>))]
[DebuggerDisplay("Count = {Count}/{Capacity}")]
public sealed class ConcurrentTLru : ConcurrentLruCore, TLruLongTicksPolicy, TelemetryPolicy>
{
diff --git a/BitFaster.Caching/Lru/FastConcurrentLru.cs b/BitFaster.Caching/Lru/FastConcurrentLru.cs
index 09662d54..b76461b8 100644
--- a/BitFaster.Caching/Lru/FastConcurrentLru.cs
+++ b/BitFaster.Caching/Lru/FastConcurrentLru.cs
@@ -4,7 +4,7 @@
namespace BitFaster.Caching.Lru
{
///
- [DebuggerTypeProxy(typeof(LruDebugView<,>))]
+ [DebuggerTypeProxy(typeof(CacheDebugView<,>))]
[DebuggerDisplay("Count = {Count}/{Capacity}")]
public sealed class FastConcurrentLru : ConcurrentLruCore, LruPolicy, NoTelemetryPolicy>
{
diff --git a/BitFaster.Caching/Lru/FastConcurrentTLru.cs b/BitFaster.Caching/Lru/FastConcurrentTLru.cs
index 422dab5c..ef805ede 100644
--- a/BitFaster.Caching/Lru/FastConcurrentTLru.cs
+++ b/BitFaster.Caching/Lru/FastConcurrentTLru.cs
@@ -5,7 +5,7 @@
namespace BitFaster.Caching.Lru
{
///
- [DebuggerTypeProxy(typeof(LruDebugView<,>))]
+ [DebuggerTypeProxy(typeof(CacheDebugView<,>))]
[DebuggerDisplay("Count = {Count}/{Capacity}")]
public sealed class FastConcurrentTLru : ConcurrentLruCore, TLruLongTicksPolicy, NoTelemetryPolicy>
{
diff --git a/BitFaster.Caching/ScopedAsyncCache.cs b/BitFaster.Caching/ScopedAsyncCache.cs
index 655170aa..806774de 100644
--- a/BitFaster.Caching/ScopedAsyncCache.cs
+++ b/BitFaster.Caching/ScopedAsyncCache.cs
@@ -14,6 +14,7 @@ namespace BitFaster.Caching
///
/// The type of keys in the cache.
/// The type of values in the cache.
+ [DebuggerTypeProxy(typeof(ScopedAsyncCacheDebugView<,>))]
[DebuggerDisplay("Count = {Count}")]
public sealed class ScopedAsyncCache : IScopedAsyncCache where V : IDisposable
{
diff --git a/BitFaster.Caching/ScopedAsyncCacheDebugView.cs b/BitFaster.Caching/ScopedAsyncCacheDebugView.cs
new file mode 100644
index 00000000..e65b05b2
--- /dev/null
+++ b/BitFaster.Caching/ScopedAsyncCacheDebugView.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+
+namespace BitFaster.Caching
+{
+ [ExcludeFromCodeCoverage]
+ internal class ScopedAsyncCacheDebugView where V : IDisposable
+ {
+ private readonly IScopedAsyncCache cache;
+
+ public ScopedAsyncCacheDebugView(IScopedAsyncCache cache)
+ {
+ if (cache is null)
+ {
+ Ex.ThrowArgNull(ExceptionArgument.cache);
+ }
+
+ this.cache = cache;
+ }
+
+ public KeyValuePair>[] Items
+ {
+ get
+ {
+ var items = new KeyValuePair>[cache.Count];
+
+ var index = 0;
+ foreach (var kvp in cache)
+ {
+ items[index++] = kvp;
+ }
+ return items;
+ }
+ }
+
+ public ICacheMetrics Metrics => cache.Metrics.Value;
+ }
+}
diff --git a/BitFaster.Caching/ScopedCache.cs b/BitFaster.Caching/ScopedCache.cs
index 99db5498..590aaf3e 100644
--- a/BitFaster.Caching/ScopedCache.cs
+++ b/BitFaster.Caching/ScopedCache.cs
@@ -13,6 +13,7 @@ namespace BitFaster.Caching
///
/// The type of keys in the cache.
/// The type of values in the cache.
+ [DebuggerTypeProxy(typeof(ScopedCacheDebugView<,>))]
[DebuggerDisplay("Count = {Count}")]
public sealed class ScopedCache : IScopedCache where V : IDisposable
{
diff --git a/BitFaster.Caching/ScopedCacheDebugView.cs b/BitFaster.Caching/ScopedCacheDebugView.cs
new file mode 100644
index 00000000..8eccb40b
--- /dev/null
+++ b/BitFaster.Caching/ScopedCacheDebugView.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+
+namespace BitFaster.Caching
+{
+ [ExcludeFromCodeCoverage]
+ internal class ScopedCacheDebugView where V : IDisposable
+ {
+ private readonly IScopedCache cache;
+
+ public ScopedCacheDebugView(IScopedCache cache)
+ {
+ if (cache is null)
+ {
+ Ex.ThrowArgNull(ExceptionArgument.cache);
+ }
+
+ this.cache = cache;
+ }
+
+ public KeyValuePair>[] Items
+ {
+ get
+ {
+ var items = new KeyValuePair>[cache.Count];
+
+ var index = 0;
+ foreach (var kvp in cache)
+ {
+ items[index++] = kvp;
+ }
+ return items;
+ }
+ }
+
+ public ICacheMetrics Metrics => cache.Metrics.Value;
+ }
+}