From f69277930eb46af04208e411df3ac9396338322e Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Wed, 22 Apr 2026 18:40:31 +0200
Subject: [PATCH 1/3] Improve XML documentation for CreativeCoders.Core APIs
- Add detailed XML summaries, parameters, and return descriptions for public methods, properties, and classes across various extension methods and utilities.
- Enhance API usability with clearer comments for reflection, collections, delegates, expressions, and generic utilities.
---
.../CreativeCoders.Core/Caching/CacheBase.cs | 21 +
.../Caching/CacheEntryNotFoundException.cs | 14 +
.../Caching/CacheExpirationMode.cs | 10 +
.../Caching/CacheExpirationPolicy.cs | 18 +
.../Caching/CacheExtensions.cs | 65 +++
.../Caching/CacheRequestResult.cs | 15 +
.../Caching/CachedValue.cs | 32 ++
.../Caching/CachedValueMode.cs | 14 +
.../Caching/Default/CacheManager.cs | 9 +
.../Caching/Default/DictionaryCache.cs | 17 +
.../CreativeCoders.Core/Caching/ICache.cs | 96 +++++
.../Caching/ICacheEntry.cs | 14 +
.../Caching/ICacheExpirationPolicy.cs | 9 +
.../Caching/ICacheManager.cs | 10 +
.../Caching/ICachedValue.cs | 11 +
.../Collections/CollectionCounter.cs | 14 +
.../Collections/CollectionsExtensions.cs | 74 ++--
.../Collections/DictionaryExtensions.cs | 63 +++
.../Collections/EnumerableExtension.cs | 400 +++++++++++++++++-
.../ExtendedObservableCollection.cs | 92 ++++
.../Collections/ItemWithIndex.cs | 16 +
.../Collections/ListExtensions.cs | 24 ++
.../ObservableCollectionSynchronizer.cs | 24 ++
.../Comparing/ComparableObject.cs | 28 ++
.../Comparing/DelegateEqualityComparer.cs | 17 +
.../Comparing/FuncComparer.cs | 12 +
.../Comparing/FuncEqualityComparer.cs | 12 +
.../Comparing/MultiComparer.cs | 10 +
.../Comparing/MultiEqualityComparer.cs | 11 +
.../Comparing/MultiFuncComparer.cs | 56 +++
.../Comparing/MultiFuncEqualitiyComparer.cs | 65 +++
.../Comparing/SortFieldInfo.cs | 16 +
.../Comparing/SortOrder.cs | 10 +
.../DelegateAsyncDisposable.cs | 10 +
.../CreativeCoders.Core/DelegateDisposable.cs | 10 +
.../CircularReferenceException.cs | 25 +-
.../Dependencies/DependencyObject.cs | 34 +-
.../DependencyObjectCollection.cs | 73 ++--
.../Dependencies/DependencyResolver.cs | 31 +-
.../Dependencies/DependencySorter.cs | 32 +-
.../Dependencies/DependencyTreeBuilder.cs | 29 +-
.../Dependencies/DependencyTreeNode.cs | 25 +-
source/Core/CreativeCoders.Core/Ensure.cs | 221 +++++-----
.../EnsureArguments/Argument.cs | 51 +--
.../EnsureArguments/ArgumentNotNull.cs | 54 +--
.../EnsureArguments/ExceptionThrower.cs | 11 +-
.../EnumerableArgumentExtensions.cs | 48 +++
.../Extensions/GuidArgumentExtensions.cs | 32 ++
.../Extensions/IoArgumentExtensions.cs | 33 ++
.../Extensions/MustArgumentExtensions.cs | 40 ++
.../Extensions/NullArgumentExtensions.cs | 19 +
.../Extensions/StringArgumentExtensions.cs | 37 ++
.../Enums/EnumExtensions.cs | 14 +
.../Enums/EnumStringConverter.cs | 8 +
.../Enums/EnumStringValueAttribute.cs | 8 +
.../CreativeCoders.Core/Enums/EnumUtils.cs | 39 ++
.../Enums/IEnumStringAttribute.cs | 6 +
.../Enums/IEnumToStringConverter.cs | 14 +
.../Error/DelegateErrorHandler.cs | 8 +
.../Error/IErrorHandler.cs | 13 +-
.../Error/NullErrorHandler.cs | 16 +-
.../CreativeCoders.Core/EventHandlerEx.cs | 12 +
.../Executing/IExecutable.cs | 6 +
.../Executing/IExecutableGeneric.cs | 8 +
.../Executing/IExecutableWithParameter.cs | 7 +
.../Executing/IExecutableWithResult.cs | 8 +
.../Executing/IExecutableWithResultGeneric.cs | 10 +
.../FluentInterfaceExtensions.cs | 71 ++++
.../IO/DirectoryCleanUp.cs | 14 +
.../IO/DirectoryExtensions.cs | 15 +
.../CreativeCoders.Core/IO/FileCleanUp.cs | 13 +-
source/Core/CreativeCoders.Core/IO/FileSys.cs | 42 +-
.../CreativeCoders.Core/IO/FileSystemEx.cs | 10 +-
.../CreativeCoders.Core/IO/IFileSystemEx.cs | 24 +-
.../IO/IOServiceCollectionExtensions.cs | 9 +
.../CreativeCoders.Core/IO/PathExtensions.cs | 28 +-
.../Core/CreativeCoders.Core/IO/PathSafety.cs | 24 +-
.../IO/StreamExtensions.cs | 45 +-
.../CreativeCoders.Core/IO/StreamWrapper.cs | 47 +-
.../Messaging/IMessenger.cs | 34 ++
.../Messaging/IMessengerRegistration.cs | 18 +
.../Messaging/Messages/CallbackMessage.cs | 10 +
.../Messaging/Messages/DialogMessage.cs | 10 +
.../Messaging/Messages/MessageBase.cs | 6 +
.../Messaging/Messenger.cs | 11 +
source/Core/CreativeCoders.Core/NullAction.cs | 13 +
source/Core/CreativeCoders.Core/NullObject.cs | 6 +
.../CreativeCoders.Core/ObjectExtensions.cs | 69 +++
.../NullableSourcePropertyConverter.cs | 8 +
.../NullableTargetPropertyConverter.cs | 7 +
.../StringSourcePropertyConverter.cs | 8 +
.../StringTargetPropertyConverter.cs | 8 +
.../ObjectLinking/IPropertyValueConverter.cs | 15 +
.../ObjectLinking/LinkDirection.cs | 14 +
.../ObjectLinking/ObjectLink.cs | 15 +
.../ObjectLinking/ObjectLinkBuilder.cs | 16 +
.../ObjectLinking/PropertyLink.cs | 10 +
.../ObjectLinking/PropertyLinkAttribute.cs | 27 ++
.../ObjectLinking/PropertyLinkDefinition.cs | 32 ++
.../ObjectLinking/PropertyLinkInfo.cs | 29 ++
.../ObjectLinking/PropertyLinkItem.cs | 21 +
.../ObjectLinking/PropertyLinkItemsBuilder.cs | 14 +
.../ObjectLinking/PropertyValueCopier.cs | 17 +
.../CreativeCoders.Core/ObservableObject.cs | 36 ++
.../Placeholders/PlaceholderReplacer.cs | 18 +
.../Reflection/AssemblyExtensions.cs | 12 +
.../Reflection/ExpressionExtensions.cs | 26 ++
.../Reflection/ExpressionUtils.cs | 88 ++++
.../Reflection/GenericArgument.cs | 14 +
.../Reflection/MethodExtensions.cs | 115 +++++
.../Reflection/MethodInfoExtensions.cs | 35 ++
.../Reflection/ParameterInfoExtensions.cs | 22 +
.../Reflection/ReflectionUtils.cs | 40 ++
.../Reflection/TypeExtensions.cs | 69 +++
.../ServiceProviderExtensions.cs | 16 +
.../CreativeCoders.Core/SysEnvironment/Env.cs | 146 +++++++
.../EnvServiceCollectionExtensions.cs | 8 +
.../SysEnvironment/EnvironmentWrapper.cs | 39 ++
.../SysEnvironment/IEnvironment.cs | 140 ++++++
.../CreativeCoders.Core/Tasking/TaskEx.cs | 19 +-
.../Text/EnumerableStringExtensions.cs | 24 ++
.../Text/Json/DefaultJsonSerializer.cs | 14 +-
.../Text/Json/IJsonSerializer.cs | 78 +++-
.../Text/JsonExtensions.cs | 55 ++-
.../CreativeCoders.Core/Text/KeyAndValue.cs | 11 +
.../Text/PatternMatcher.cs | 13 +-
.../CreativeCoders.Core/Text/RandomString.cs | 28 +-
.../Text/StringExtension.cs | 120 +++++-
.../Core/CreativeCoders.Core/Text/TextSpan.cs | 49 +--
.../Threading/AcquireLockFailedException.cs | 20 +
.../Threading/AcquireReaderLock.cs | 21 +
.../Threading/AcquireUpgradeableReaderLock.cs | 31 ++
.../Threading/AcquireWriterLock.cs | 27 ++
.../Threading/ConcurrentList.cs | 42 ++
.../Threading/ILockingMechanism.cs | 23 +
.../Threading/IUpgradeableLockingMechanism.cs | 14 +
.../Threading/LockExtension.cs | 74 ++++
.../Threading/LockLockingMechanism.cs | 17 +
.../Threading/LockSlimLockingMechanism.cs | 19 +
.../Threading/MutexLock.cs | 10 +
.../Threading/NoLockingMechanism.cs | 16 +-
.../Threading/SimpleMonitor.cs | 14 +
.../Threading/SynchronizationMethod.cs | 14 +
.../Threading/SynchronizedValue.cs | 53 +++
.../Threading/TaskExtensions.cs | 21 +
.../Threading/UpgradeableReadAction.cs | 8 +
.../Threading/UpgradeableReadFunc.cs | 10 +
.../AcceptForVisitorNotFoundException.cs | 9 +
.../Visitors/IVisitable.cs | 7 +
.../Visitors/IVisitableGeneric.cs | 10 +
.../Visitors/IVisitableSubItems.cs | 7 +
.../CreativeCoders.Core/Visitors/IVisitor.cs | 10 +
.../Visitors/IVisitorInfo.cs | 8 +
.../Visitors/ListVisitor.cs | 13 +
.../CreativeCoders.Core/Visitors/Visitable.cs | 13 +
.../Visitors/VisitableAction.cs | 10 +
.../Visitors/VisitorBase.cs | 19 +
.../Weak/KeepOwnerAliveMode.cs | 14 +
.../Weak/NullDisposable.cs | 4 +
.../CreativeCoders.Core/Weak/WeakAction.cs | 24 ++
.../Weak/WeakActionGeneric.cs | 27 ++
.../Core/CreativeCoders.Core/Weak/WeakBase.cs | 30 ++
.../Core/CreativeCoders.Core/Weak/WeakFunc.cs | 51 +++
.../Weak/WeakReferenceExtensions.cs | 15 +
164 files changed, 4487 insertions(+), 504 deletions(-)
diff --git a/source/Core/CreativeCoders.Core/Caching/CacheBase.cs b/source/Core/CreativeCoders.Core/Caching/CacheBase.cs
index 6d25c206..ffa3780a 100644
--- a/source/Core/CreativeCoders.Core/Caching/CacheBase.cs
+++ b/source/Core/CreativeCoders.Core/Caching/CacheBase.cs
@@ -3,43 +3,64 @@
namespace CreativeCoders.Core.Caching;
+///
+/// Provides an abstract base class for implementations. Overloads without
+/// an expiration policy delegate to the overloads that accept an
+/// using .
+///
+/// The type of the cache key.
+/// The type of the cached value.
public abstract class CacheBase : ICache
{
+ ///
public virtual TValue GetOrAdd(TKey key, Func getValue, string regionName = null)
{
return GetOrAdd(key, getValue, CacheExpirationPolicy.NeverExpire, regionName);
}
+ ///
public abstract TValue GetOrAdd(TKey key, Func getValue, ICacheExpirationPolicy expirationPolicy,
string regionName = null);
+ ///
public virtual Task GetOrAddAsync(TKey key, Func getValue, string regionName = null)
{
return GetOrAddAsync(key, getValue, CacheExpirationPolicy.NeverExpire, regionName);
}
+ ///
public abstract Task GetOrAddAsync(TKey key, Func getValue,
ICacheExpirationPolicy expirationPolicy, string regionName = null);
+ ///
public abstract bool TryGet(TKey key, out TValue value, string regionName = null);
+ ///
public abstract Task> TryGetAsync(TKey key, string regionName = null);
+ ///
public abstract void AddOrUpdate(TKey key, TValue value, string regionName = null);
+ ///
public abstract void AddOrUpdate(TKey key, TValue value, ICacheExpirationPolicy expirationPolicy,
string regionName = null);
+ ///
public abstract Task AddOrUpdateAsync(TKey key, TValue value, string regionName = null);
+ ///
public abstract Task AddOrUpdateAsync(TKey key, TValue value, ICacheExpirationPolicy expirationPolicy,
string regionName = null);
+ ///
public abstract void Clear(string regionName = null);
+ ///
public abstract Task ClearAsync(string regionName = null);
+ ///
public abstract void Remove(TKey key, string regionName = null);
+ ///
public abstract Task RemoveAsync(TKey key, string regionName = null);
}
diff --git a/source/Core/CreativeCoders.Core/Caching/CacheEntryNotFoundException.cs b/source/Core/CreativeCoders.Core/Caching/CacheEntryNotFoundException.cs
index 19b43a16..2b06214e 100644
--- a/source/Core/CreativeCoders.Core/Caching/CacheEntryNotFoundException.cs
+++ b/source/Core/CreativeCoders.Core/Caching/CacheEntryNotFoundException.cs
@@ -2,9 +2,17 @@
namespace CreativeCoders.Core.Caching;
+///
+/// The exception that is thrown when a cache entry with the specified key and region is not found.
+///
[Serializable]
public class CacheEntryNotFoundException : Exception
{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Cache key that was not found.
+ /// Cache region name that was searched, or for the default region.
public CacheEntryNotFoundException(string key, string regionName) :
base($"No cache entry for key = '{key}' and region = '{regionName ?? string.Empty}' found")
{
@@ -12,7 +20,13 @@ public CacheEntryNotFoundException(string key, string regionName) :
RegionName = regionName ?? string.Empty;
}
+ ///
+ /// Gets the cache key that was not found.
+ ///
public string Key { get; }
+ ///
+ /// Gets the name of the cache region that was searched.
+ ///
public string RegionName { get; }
}
diff --git a/source/Core/CreativeCoders.Core/Caching/CacheExpirationMode.cs b/source/Core/CreativeCoders.Core/Caching/CacheExpirationMode.cs
index 56a65f5e..5372008a 100644
--- a/source/Core/CreativeCoders.Core/Caching/CacheExpirationMode.cs
+++ b/source/Core/CreativeCoders.Core/Caching/CacheExpirationMode.cs
@@ -1,7 +1,17 @@
namespace CreativeCoders.Core.Caching;
+///
+/// Specifies the mode used to determine when a cache entry expires.
+///
public enum CacheExpirationMode
{
+ ///
+ /// The cache entry never expires.
+ ///
NeverExpire,
+
+ ///
+ /// The cache entry expires at a specific absolute date and time.
+ ///
AbsoluteDateTime
}
diff --git a/source/Core/CreativeCoders.Core/Caching/CacheExpirationPolicy.cs b/source/Core/CreativeCoders.Core/Caching/CacheExpirationPolicy.cs
index 2c2345fe..f14811dc 100644
--- a/source/Core/CreativeCoders.Core/Caching/CacheExpirationPolicy.cs
+++ b/source/Core/CreativeCoders.Core/Caching/CacheExpirationPolicy.cs
@@ -3,17 +3,33 @@
namespace CreativeCoders.Core.Caching;
+///
+/// Provides a default implementation of with support for
+/// never-expire and absolute-date-time expiration modes.
+///
[PublicAPI]
public class CacheExpirationPolicy : ICacheExpirationPolicy
{
+ ///
+ /// A shared policy instance that indicates cache entries should never expire.
+ ///
public static readonly CacheExpirationPolicy NeverExpire =
new CacheExpirationPolicy(CacheExpirationMode.NeverExpire);
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Expiration mode for this policy.
public CacheExpirationPolicy(CacheExpirationMode expirationMode)
{
ExpirationMode = expirationMode;
}
+ ///
+ /// Creates a new expiration policy that expires at the specified absolute date and time.
+ ///
+ /// Absolute date and time at which the cache entry expires. The value is converted to UTC.
+ /// A new configured for absolute-date-time expiration.
public static CacheExpirationPolicy AfterAbsoluteDateTime(DateTime absoluteDateTime)
{
return new CacheExpirationPolicy(CacheExpirationMode.AbsoluteDateTime)
@@ -22,7 +38,9 @@ public static CacheExpirationPolicy AfterAbsoluteDateTime(DateTime absoluteDateT
};
}
+ ///
public CacheExpirationMode ExpirationMode { get; }
+ ///
public DateTime AbsoluteDateTime { get; private set; }
}
diff --git a/source/Core/CreativeCoders.Core/Caching/CacheExtensions.cs b/source/Core/CreativeCoders.Core/Caching/CacheExtensions.cs
index 937bcf51..1bd05bb0 100644
--- a/source/Core/CreativeCoders.Core/Caching/CacheExtensions.cs
+++ b/source/Core/CreativeCoders.Core/Caching/CacheExtensions.cs
@@ -2,8 +2,22 @@
namespace CreativeCoders.Core.Caching;
+///
+/// Provides extension methods for that simplify common value retrieval patterns.
+///
public static class CacheExtensions
{
+ ///
+ /// Gets the value associated with the specified key, optionally throwing an exception when the key is not found.
+ ///
+ /// The type of the cache key.
+ /// The type of the cached value.
+ /// Cache to retrieve the value from.
+ /// Cache key to look up.
+ /// When , a is thrown if the key is not found; otherwise, the default value is returned.
+ /// Optional cache region name. When , the default region is used.
+ /// The cached value, or the default value when is and the key is not found.
+ /// The does not exist and is .
public static TValue GetValue(this ICache cache, TKey key,
bool throwExceptionIfKeyNotExists, string regionName = null)
{
@@ -20,6 +34,17 @@ public static TValue GetValue(this ICache cache, TKe
return default;
}
+ ///
+ /// Asynchronously gets the value associated with the specified key, optionally throwing an exception when the key is not found.
+ ///
+ /// The type of the cache key.
+ /// The type of the cached value.
+ /// Cache to retrieve the value from.
+ /// Cache key to look up.
+ /// When , a is thrown if the key is not found; otherwise, the default value is returned.
+ /// Optional cache region name. When , the default region is used.
+ /// A task that represents the asynchronous operation. The task result contains the cached value, or the default value when is and the key is not found.
+ /// The does not exist and is .
public static async Task GetValueAsync(this ICache cache, TKey key,
bool throwExceptionIfKeyNotExists, string regionName = null)
{
@@ -38,24 +63,64 @@ public static async Task GetValueAsync(this ICache
+ /// Gets the value associated with the specified key, throwing a when the key is not found.
+ ///
+ /// The type of the cache key.
+ /// The type of the cached value.
+ /// Cache to retrieve the value from.
+ /// Cache key to look up.
+ /// Optional cache region name. When , the default region is used.
+ /// The cached value.
+ /// The does not exist in the cache.
public static TValue GetValue(this ICache cache, TKey key,
string regionName = null)
{
return cache.GetValue(key, true, regionName);
}
+ ///
+ /// Asynchronously gets the value associated with the specified key, throwing a when the key is not found.
+ ///
+ /// The type of the cache key.
+ /// The type of the cached value.
+ /// Cache to retrieve the value from.
+ /// Cache key to look up.
+ /// Optional cache region name. When , the default region is used.
+ /// A task that represents the asynchronous operation. The task result contains the cached value.
+ /// The does not exist in the cache.
public static Task GetValueAsync(this ICache cache, TKey key,
string regionName = null)
{
return cache.GetValueAsync(key, true, regionName);
}
+ ///
+ /// Gets the value associated with the specified key, or returns a default value when the key is not found.
+ ///
+ /// The type of the cache key.
+ /// The type of the cached value.
+ /// Cache to retrieve the value from.
+ /// Cache key to look up.
+ /// Value to return when the key is not found.
+ /// Optional cache region name. When , the default region is used.
+ /// The cached value if the key exists; otherwise, .
public static TValue GetValueOrDefault(this ICache cache, TKey key,
TValue defaultValue, string regionName = null)
{
return cache.TryGet(key, out var value, regionName) ? value : defaultValue;
}
+ ///
+ /// Asynchronously gets the value associated with the specified key, or returns a default value when the key is not found.
+ ///
+ /// The type of the cache key.
+ /// The type of the cached value.
+ /// Cache to retrieve the value from.
+ /// Cache key to look up.
+ /// Value to return when the key is not found.
+ /// Optional cache region name. When , the default region is used.
+ /// A task that represents the asynchronous operation. The task result contains the cached value if the key exists; otherwise, .
public static async Task GetValueOrDefaultAsync(this ICache cache,
TKey key,
TValue defaultValue, string regionName = null)
diff --git a/source/Core/CreativeCoders.Core/Caching/CacheRequestResult.cs b/source/Core/CreativeCoders.Core/Caching/CacheRequestResult.cs
index 7f23640a..67ee96d2 100644
--- a/source/Core/CreativeCoders.Core/Caching/CacheRequestResult.cs
+++ b/source/Core/CreativeCoders.Core/Caching/CacheRequestResult.cs
@@ -1,14 +1,29 @@
namespace CreativeCoders.Core.Caching;
+///
+/// Represents the result of a cache lookup, indicating whether the entry exists and its value.
+///
+/// The type of the cached value.
public class CacheRequestResult
{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Indicates whether the cache entry was found.
+ /// Cached value, or the default value if the entry does not exist.
public CacheRequestResult(bool entryExists, TValue value)
{
EntryExists = entryExists;
Value = value;
}
+ ///
+ /// Gets a value indicating whether the requested cache entry exists.
+ ///
public bool EntryExists { get; }
+ ///
+ /// Gets the cached value. The value is meaningful only when is .
+ ///
public TValue Value { get; }
}
diff --git a/source/Core/CreativeCoders.Core/Caching/CachedValue.cs b/source/Core/CreativeCoders.Core/Caching/CachedValue.cs
index d34e880a..e041dff2 100644
--- a/source/Core/CreativeCoders.Core/Caching/CachedValue.cs
+++ b/source/Core/CreativeCoders.Core/Caching/CachedValue.cs
@@ -4,6 +4,12 @@
namespace CreativeCoders.Core.Caching;
+///
+/// Provides a lazily resolved cached value backed by an . The retrieval
+/// strategy is determined by the selected at construction time.
+///
+/// The type of the cache key.
+/// The type of the cached value.
[PublicAPI]
public class CachedValue : ICachedValue
{
@@ -21,6 +27,15 @@ public class CachedValue : ICachedValue
private readonly CachedValueMode _cachedValueMode;
+ ///
+ /// Initializes a new instance of the class that uses the
+ /// strategy with a factory delegate and expiration policy.
+ ///
+ /// Underlying cache to retrieve or store values in.
+ /// Cache key used for lookup.
+ /// Factory delegate invoked to produce the value when the key is not found.
+ /// Expiration policy applied to newly added entries.
+ /// Optional cache region name. When , the default region is used.
public CachedValue(ICache cache, TKey key, Func getValue,
ICacheExpirationPolicy expirationPolicy, string regionName = null)
{
@@ -33,6 +48,13 @@ public CachedValue(ICache cache, TKey key, Func getValue,
_regionName = regionName;
}
+ ///
+ /// Initializes a new instance of the class that uses the
+ /// strategy, throwing an exception when the key is not found.
+ ///
+ /// Underlying cache to retrieve values from.
+ /// Cache key used for lookup.
+ /// Optional cache region name. When , the default region is used.
public CachedValue(ICache cache, TKey key, string regionName = null)
{
_cachedValueMode = CachedValueMode.GetValue;
@@ -42,6 +64,14 @@ public CachedValue(ICache cache, TKey key, string regionName = nul
_regionName = regionName;
}
+ ///
+ /// Initializes a new instance of the class that uses the
+ /// strategy, returning a default value when the key is not found.
+ ///
+ /// Underlying cache to retrieve values from.
+ /// Cache key used for lookup.
+ /// Value returned when the key is not found in the cache.
+ /// Optional cache region name. When , the default region is used.
public CachedValue(ICache cache, TKey key, TValue defaultValue, string regionName = null)
{
_cachedValueMode = CachedValueMode.GetValueOrDefault;
@@ -63,6 +93,7 @@ private TValue GetValue()
};
}
+ ///
public Task GetValueAsync()
{
return _cachedValueMode switch
@@ -75,5 +106,6 @@ public Task GetValueAsync()
};
}
+ ///
public TValue Value => GetValue();
}
diff --git a/source/Core/CreativeCoders.Core/Caching/CachedValueMode.cs b/source/Core/CreativeCoders.Core/Caching/CachedValueMode.cs
index dca6254f..4e9bd4a9 100644
--- a/source/Core/CreativeCoders.Core/Caching/CachedValueMode.cs
+++ b/source/Core/CreativeCoders.Core/Caching/CachedValueMode.cs
@@ -1,8 +1,22 @@
namespace CreativeCoders.Core.Caching;
+///
+/// Specifies the retrieval strategy used by a instance.
+///
public enum CachedValueMode
{
+ ///
+ /// Gets the cached value or adds it using a factory delegate if the key does not exist.
+ ///
GetOrAdd,
+
+ ///
+ /// Gets the cached value, throwing an exception if the key does not exist.
+ ///
GetValue,
+
+ ///
+ /// Gets the cached value, returning a default value if the key does not exist.
+ ///
GetValueOrDefault
}
diff --git a/source/Core/CreativeCoders.Core/Caching/Default/CacheManager.cs b/source/Core/CreativeCoders.Core/Caching/Default/CacheManager.cs
index b9380092..7a63af9e 100644
--- a/source/Core/CreativeCoders.Core/Caching/Default/CacheManager.cs
+++ b/source/Core/CreativeCoders.Core/Caching/Default/CacheManager.cs
@@ -1,7 +1,16 @@
namespace CreativeCoders.Core.Caching.Default;
+///
+/// Provides a static factory for creating default in-memory cache instances.
+///
public static class CacheManager
{
+ ///
+ /// Creates a new instance.
+ ///
+ /// The type of the cache key.
+ /// The type of the cached value.
+ /// A new backed by an in-memory dictionary.
public static ICache CreateCache()
{
return new DictionaryCache();
diff --git a/source/Core/CreativeCoders.Core/Caching/Default/DictionaryCache.cs b/source/Core/CreativeCoders.Core/Caching/Default/DictionaryCache.cs
index bf880a23..5cdc645a 100644
--- a/source/Core/CreativeCoders.Core/Caching/Default/DictionaryCache.cs
+++ b/source/Core/CreativeCoders.Core/Caching/Default/DictionaryCache.cs
@@ -3,10 +3,16 @@
namespace CreativeCoders.Core.Caching.Default;
+///
+/// Provides a dictionary-based in-memory implementation of .
+///
+/// The type of the cache key.
+/// The type of the cached value.
public class DictionaryCache : CacheBase
{
private readonly CacheRegions _regions = new CacheRegions();
+ ///
public override TValue GetOrAdd(TKey key, Func getValue, ICacheExpirationPolicy expirationPolicy,
string regionName = null)
{
@@ -21,12 +27,14 @@ public override TValue GetOrAdd(TKey key, Func getValue, ICacheExpiratio
return newValue;
}
+ ///
public override Task GetOrAddAsync(TKey key, Func getValue,
ICacheExpirationPolicy expirationPolicy, string regionName = null)
{
return Task.FromResult(GetOrAdd(key, getValue, expirationPolicy, regionName));
}
+ ///
public override bool TryGet(TKey key, out TValue value, string regionName = null)
{
if (!_regions.TryGetValue(key, out var cacheEntry, regionName))
@@ -46,6 +54,7 @@ public override bool TryGet(TKey key, out TValue value, string regionName = null
return true;
}
+ ///
public override Task> TryGetAsync(TKey key, string regionName = null)
{
return Task.FromResult(
@@ -55,6 +64,7 @@ public override Task> TryGetAsync(TKey key, string re
);
}
+ ///
public override void AddOrUpdate(TKey key, TValue value, string regionName = null)
{
_regions.Set(key,
@@ -62,12 +72,14 @@ public override void AddOrUpdate(TKey key, TValue value, string regionName = nul
regionName);
}
+ ///
public override void AddOrUpdate(TKey key, TValue value, ICacheExpirationPolicy expirationPolicy,
string regionName = null)
{
_regions.Set(key, new CacheEntry(key, expirationPolicy) { Value = value }, regionName);
}
+ ///
public override Task AddOrUpdateAsync(TKey key, TValue value, string regionName = null)
{
AddOrUpdate(key, value, regionName);
@@ -75,6 +87,7 @@ public override Task AddOrUpdateAsync(TKey key, TValue value, string regionName
return Task.CompletedTask;
}
+ ///
public override Task AddOrUpdateAsync(TKey key, TValue value, ICacheExpirationPolicy expirationPolicy,
string regionName = null)
{
@@ -83,22 +96,26 @@ public override Task AddOrUpdateAsync(TKey key, TValue value, ICacheExpirationPo
return Task.CompletedTask;
}
+ ///
public override void Clear(string regionName = null)
{
_regions.Clear(regionName);
}
+ ///
public override Task ClearAsync(string regionName = null)
{
Clear(regionName);
return Task.CompletedTask;
}
+ ///
public override void Remove(TKey key, string regionName = null)
{
_regions.TryRemove(key, regionName);
}
+ ///
public override Task RemoveAsync(TKey key, string regionName = null)
{
Remove(key, regionName);
diff --git a/source/Core/CreativeCoders.Core/Caching/ICache.cs b/source/Core/CreativeCoders.Core/Caching/ICache.cs
index 1a8c771d..4eaa1660 100644
--- a/source/Core/CreativeCoders.Core/Caching/ICache.cs
+++ b/source/Core/CreativeCoders.Core/Caching/ICache.cs
@@ -4,38 +4,134 @@
namespace CreativeCoders.Core.Caching;
+///
+/// Defines a key-value cache that supports regions, expiration policies, and asynchronous operations.
+///
+/// The type of the cache key.
+/// The type of the cached value.
[PublicAPI]
public interface ICache
{
+ ///
+ /// Gets the value associated with the specified key, or adds a new value using the provided factory if the key does not exist.
+ ///
+ /// Cache key to look up or insert.
+ /// Factory delegate invoked to produce the value when the key is not found.
+ /// Optional cache region name. When , the default region is used.
+ /// The cached or newly added value.
TValue GetOrAdd(TKey key, Func getValue, string regionName = null);
+ ///
+ /// Gets the value associated with the specified key, or adds a new value with the given expiration policy if the key does not exist.
+ ///
+ /// Cache key to look up or insert.
+ /// Factory delegate invoked to produce the value when the key is not found.
+ /// Expiration policy applied to the new cache entry.
+ /// Optional cache region name. When , the default region is used.
+ /// The cached or newly added value.
TValue GetOrAdd(TKey key, Func getValue, ICacheExpirationPolicy expirationPolicy,
string regionName = null);
+ ///
+ /// Asynchronously gets the value associated with the specified key, or adds a new value using the provided factory if the key does not exist.
+ ///
+ /// Cache key to look up or insert.
+ /// Factory delegate invoked to produce the value when the key is not found.
+ /// Optional cache region name. When , the default region is used.
+ /// A task that represents the asynchronous operation. The task result contains the cached or newly added value.
Task GetOrAddAsync(TKey key, Func getValue, string regionName = null);
+ ///
+ /// Asynchronously gets the value associated with the specified key, or adds a new value with the given expiration policy if the key does not exist.
+ ///
+ /// Cache key to look up or insert.
+ /// Factory delegate invoked to produce the value when the key is not found.
+ /// Expiration policy applied to the new cache entry.
+ /// Optional cache region name. When , the default region is used.
+ /// A task that represents the asynchronous operation. The task result contains the cached or newly added value.
Task GetOrAddAsync(TKey key, Func getValue, ICacheExpirationPolicy expirationPolicy,
string regionName = null);
+ ///
+ /// Attempts to get the value associated with the specified key.
+ ///
+ /// Cache key to look up.
+ /// When this method returns, contains the cached value if the key was found; otherwise, the default value.
+ /// Optional cache region name. When , the default region is used.
+ /// if the key exists in the cache; otherwise, .
bool TryGet(TKey key, out TValue value, string regionName = null);
+ ///
+ /// Asynchronously attempts to get the value associated with the specified key.
+ ///
+ /// Cache key to look up.
+ /// Optional cache region name. When , the default region is used.
+ /// A task that represents the asynchronous operation. The task result contains a indicating whether the entry exists and its value.
Task> TryGetAsync(TKey key, string regionName = null);
+ ///
+ /// Adds a new entry or updates an existing entry in the cache with the specified key and value.
+ ///
+ /// Cache key to add or update.
+ /// Value to store in the cache.
+ /// Optional cache region name. When , the default region is used.
void AddOrUpdate(TKey key, TValue value, string regionName = null);
+ ///
+ /// Adds a new entry or updates an existing entry in the cache with the specified key, value, and expiration policy.
+ ///
+ /// Cache key to add or update.
+ /// Value to store in the cache.
+ /// Expiration policy applied to the cache entry.
+ /// Optional cache region name. When , the default region is used.
void AddOrUpdate(TKey key, TValue value, ICacheExpirationPolicy expirationPolicy,
string regionName = null);
+ ///
+ /// Asynchronously adds a new entry or updates an existing entry in the cache with the specified key and value.
+ ///
+ /// Cache key to add or update.
+ /// Value to store in the cache.
+ /// Optional cache region name. When , the default region is used.
+ /// A task that represents the asynchronous operation.
Task AddOrUpdateAsync(TKey key, TValue value, string regionName = null);
+ ///
+ /// Asynchronously adds a new entry or updates an existing entry in the cache with the specified key, value, and expiration policy.
+ ///
+ /// Cache key to add or update.
+ /// Value to store in the cache.
+ /// Expiration policy applied to the cache entry.
+ /// Optional cache region name. When , the default region is used.
+ /// A task that represents the asynchronous operation.
Task AddOrUpdateAsync(TKey key, TValue value, ICacheExpirationPolicy expirationPolicy,
string regionName = null);
+ ///
+ /// Removes all entries from the cache, optionally scoped to a specific region.
+ ///
+ /// Optional cache region name. When , the default region is cleared.
void Clear(string regionName = null);
+ ///
+ /// Asynchronously removes all entries from the cache, optionally scoped to a specific region.
+ ///
+ /// Optional cache region name. When , the default region is cleared.
+ /// A task that represents the asynchronous operation.
Task ClearAsync(string regionName = null);
+ ///
+ /// Removes the entry with the specified key from the cache.
+ ///
+ /// Cache key to remove.
+ /// Optional cache region name. When , the default region is used.
void Remove(TKey key, string regionName = null);
+ ///
+ /// Asynchronously removes the entry with the specified key from the cache.
+ ///
+ /// Cache key to remove.
+ /// Optional cache region name. When , the default region is used.
+ /// A task that represents the asynchronous operation.
Task RemoveAsync(TKey key, string regionName = null);
}
diff --git a/source/Core/CreativeCoders.Core/Caching/ICacheEntry.cs b/source/Core/CreativeCoders.Core/Caching/ICacheEntry.cs
index cafde480..0be40a04 100644
--- a/source/Core/CreativeCoders.Core/Caching/ICacheEntry.cs
+++ b/source/Core/CreativeCoders.Core/Caching/ICacheEntry.cs
@@ -2,12 +2,26 @@
namespace CreativeCoders.Core.Caching;
+///
+/// Represents a single entry stored in a cache, including its key, value, and expiration policy.
+///
+/// The type of the cache key.
+/// The type of the cached value.
[PublicAPI]
public interface ICacheEntry
{
+ ///
+ /// Gets the key that identifies this cache entry.
+ ///
TKey Key { get; }
+ ///
+ /// Gets or sets the value stored in this cache entry.
+ ///
TValue Value { get; set; }
+ ///
+ /// Gets the expiration policy governing when this cache entry expires.
+ ///
ICacheExpirationPolicy ExpirationPolicy { get; }
}
diff --git a/source/Core/CreativeCoders.Core/Caching/ICacheExpirationPolicy.cs b/source/Core/CreativeCoders.Core/Caching/ICacheExpirationPolicy.cs
index 03104745..066776a5 100644
--- a/source/Core/CreativeCoders.Core/Caching/ICacheExpirationPolicy.cs
+++ b/source/Core/CreativeCoders.Core/Caching/ICacheExpirationPolicy.cs
@@ -2,9 +2,18 @@
namespace CreativeCoders.Core.Caching;
+///
+/// Defines the expiration behavior for a cache entry.
+///
public interface ICacheExpirationPolicy
{
+ ///
+ /// Gets the expiration mode that determines how the cache entry expires.
+ ///
CacheExpirationMode ExpirationMode { get; }
+ ///
+ /// Gets the absolute UTC date and time at which the cache entry expires.
+ ///
DateTime AbsoluteDateTime { get; }
}
diff --git a/source/Core/CreativeCoders.Core/Caching/ICacheManager.cs b/source/Core/CreativeCoders.Core/Caching/ICacheManager.cs
index 380ac5d0..4d4e722c 100644
--- a/source/Core/CreativeCoders.Core/Caching/ICacheManager.cs
+++ b/source/Core/CreativeCoders.Core/Caching/ICacheManager.cs
@@ -2,8 +2,18 @@
namespace CreativeCoders.Core.Caching;
+///
+/// Provides access to named cache instances.
+///
[PublicAPI]
public interface ICacheManager
{
+ ///
+ /// Gets or creates a cache instance with the specified name.
+ ///
+ /// The type of the cache key.
+ /// The type of the cached value.
+ /// Unique name identifying the cache.
+ /// The instance associated with the given name.
ICache GetCache(string name);
}
diff --git a/source/Core/CreativeCoders.Core/Caching/ICachedValue.cs b/source/Core/CreativeCoders.Core/Caching/ICachedValue.cs
index 4a005cc1..d0b0ac22 100644
--- a/source/Core/CreativeCoders.Core/Caching/ICachedValue.cs
+++ b/source/Core/CreativeCoders.Core/Caching/ICachedValue.cs
@@ -3,10 +3,21 @@
namespace CreativeCoders.Core.Caching;
+///
+/// Represents a lazily resolved cached value that retrieves its data from an underlying cache.
+///
+/// The type of the cached value.
[PublicAPI]
public interface ICachedValue
{
+ ///
+ /// Asynchronously retrieves the cached value.
+ ///
+ /// A task that represents the asynchronous operation. The task result contains the cached value.
Task GetValueAsync();
+ ///
+ /// Gets the cached value synchronously.
+ ///
TValue Value { get; }
}
diff --git a/source/Core/CreativeCoders.Core/Collections/CollectionCounter.cs b/source/Core/CreativeCoders.Core/Collections/CollectionCounter.cs
index 348b62ab..9fcdd494 100644
--- a/source/Core/CreativeCoders.Core/Collections/CollectionCounter.cs
+++ b/source/Core/CreativeCoders.Core/Collections/CollectionCounter.cs
@@ -6,11 +6,25 @@
#nullable enable
namespace CreativeCoders.Core.Collections;
+///
+/// Provides pre-compiled, high-performance counting delegates for collections of type
+/// . When exposes a Count property,
+/// it is accessed directly via a compiled expression; otherwise, the sequence is enumerated.
+///
+/// The collection type, which must implement .
public static class CollectionCounter
where T : IEnumerable
{
+ ///
+ /// Gets a delegate that counts the elements in a collection, stopping at the specified maximum.
+ /// The first parameter is the collection to count; the second parameter is the maximum count
+ /// (0 means no limit).
+ ///
public static Func CountMax { get; } = GetCountFunc();
+ ///
+ /// Gets a delegate that counts all elements in a collection with no upper limit.
+ ///
public static Func Count { get; } = items => CountMax(items, 0);
private static Func GetCountFunc()
diff --git a/source/Core/CreativeCoders.Core/Collections/CollectionsExtensions.cs b/source/Core/CreativeCoders.Core/Collections/CollectionsExtensions.cs
index 614614ad..e3779557 100644
--- a/source/Core/CreativeCoders.Core/Collections/CollectionsExtensions.cs
+++ b/source/Core/CreativeCoders.Core/Collections/CollectionsExtensions.cs
@@ -6,21 +6,23 @@
#nullable enable
namespace CreativeCoders.Core.Collections;
+///
+/// Provides fast counting and emptiness-check extension methods for sequences.
+///
[SuppressMessage("CodeQuality", "IDE0079:Remove unnecessary suppression", Justification = "")]
public static class CollectionsExtensions
{
- ///-------------------------------------------------------------------------------------------------
///
- /// An IEnumerable extension method that do a fast count. The method first tries if
- /// is a collection and reads Count if possible.
+ /// Counts the elements in the source sequence using the fastest available strategy.
+ /// If implements a known collection interface, the Count
+ /// property is read directly; otherwise the sequence is enumerated.
///
- ///
- /// The items to act on.
- /// (Optional) Number of maximum count if must
- /// be enumerated for counting.
- ///
- /// The count.
- ///-------------------------------------------------------------------------------------------------
+ /// The source sequence to count.
+ ///
+ /// Maximum number of elements to count when the sequence must be enumerated.
+ /// A value of 0 means no limit.
+ ///
+ /// The number of elements in the sequence, capped at when applicable.
[SuppressMessage("ReSharper", "PossibleMultipleEnumeration")]
public static int FastCount(this IEnumerable items, int maxCount = 0)
{
@@ -29,17 +31,17 @@ public static int FastCount(this IEnumerable items, int maxCount = 0)
: items.EnumerableCount(maxCount);
}
- ///-------------------------------------------------------------------------------------------------
///
- /// An IEnumerable extension method that fast checks if the items count is in range.
+ /// Determines whether the number of elements in the source sequence falls within the specified range,
+ /// using the fastest available counting strategy.
///
- ///
- /// The items to act on.
- /// Number of minimum count.
- /// Number of maximum count.
- ///
- /// True if items count is in range, false otherwise.
- ///-------------------------------------------------------------------------------------------------
+ /// The source sequence to evaluate.
+ /// The inclusive lower bound of the acceptable count.
+ /// The exclusive upper bound of the acceptable count.
+ ///
+ /// if the element count is greater than or equal to
+ /// and less than ; otherwise, .
+ ///
[SuppressMessage("ReSharper", "PossibleMultipleEnumeration")]
public static bool FastCountInRange(this IEnumerable items, int minCount, int maxCount)
{
@@ -82,13 +84,13 @@ private static int EnumerableCount(this IEnumerable items, int maxCount)
return count;
}
- ///-------------------------------------------------------------------------------------------------
- /// An IEnumerable extension method that fast empty.
- ///
- /// The items to act on.
- ///
- /// True if it succeeds, false if it fails.
- ///-------------------------------------------------------------------------------------------------
+ ///
+ /// Determines whether the source sequence contains no elements, using the fastest available strategy.
+ ///
+ /// The source sequence to evaluate.
+ ///
+ /// if the sequence is empty; otherwise, .
+ ///
[SuppressMessage("ReSharper", "PossibleMultipleEnumeration")]
public static bool FastEmpty(this IEnumerable items)
{
@@ -108,17 +110,19 @@ bool MoveNext()
}
}
- ///-------------------------------------------------------------------------------------------------
///
- /// An IEnumerable extension method that attempts to get the collection count from the
- /// given IEnumerable.
+ /// Attempts to retrieve the element count directly from a known collection interface
+ /// without enumerating the sequence.
///
- ///
- /// The items to act on.
- /// [out] Count in items.
- ///
- /// True if it Count can be read from a collection, false otherwise.
- ///-------------------------------------------------------------------------------------------------
+ /// The source sequence to inspect.
+ ///
+ /// When this method returns , contains the number of elements;
+ /// otherwise, 0.
+ ///
+ ///
+ /// if the count was obtained from a collection property;
+ /// otherwise, .
+ ///
public static bool TryGetCollectionCount(this IEnumerable items, out int count)
{
switch (items)
diff --git a/source/Core/CreativeCoders.Core/Collections/DictionaryExtensions.cs b/source/Core/CreativeCoders.Core/Collections/DictionaryExtensions.cs
index cfc7b2b6..03a55e6c 100644
--- a/source/Core/CreativeCoders.Core/Collections/DictionaryExtensions.cs
+++ b/source/Core/CreativeCoders.Core/Collections/DictionaryExtensions.cs
@@ -5,8 +5,23 @@
namespace CreativeCoders.Core.Collections;
+///
+/// Provides extension methods for and ,
+/// including reverse-lookup and typed conversion operations.
+///
public static class DictionaryExtensions
{
+ ///
+ /// Returns the key associated with the specified value in the dictionary.
+ ///
+ /// The type of keys in the dictionary.
+ /// The type of values in the dictionary.
+ /// The dictionary to search.
+ /// The value whose associated key is returned.
+ /// The key associated with .
+ ///
+ /// No entry with the specified exists in the dictionary.
+ ///
public static TKey GetKeyByValue(this IDictionary dictionary, TValue value)
{
if (TryGetKeyByValue(dictionary, value, out var key))
@@ -17,6 +32,20 @@ public static TKey GetKeyByValue(this IDictionary di
throw new KeyNotFoundException();
}
+ ///
+ /// Attempts to find the key associated with the specified value in the dictionary.
+ ///
+ /// The type of keys in the dictionary.
+ /// The type of values in the dictionary.
+ /// The dictionary to search.
+ /// The value whose associated key is returned.
+ ///
+ /// When this method returns , contains the key associated with ;
+ /// otherwise, the default value of .
+ ///
+ ///
+ /// if a matching entry was found; otherwise, .
+ ///
public static bool TryGetKeyByValue(this IDictionary dictionary, TValue value,
out TKey key)
{
@@ -31,6 +60,22 @@ public static bool TryGetKeyByValue(this IDictionary
return false;
}
+ ///
+ /// Converts a non-generic to a strongly-typed
+ /// by casting each key and value.
+ ///
+ /// The target key type.
+ /// The target value type.
+ /// The non-generic dictionary to convert.
+ ///
+ /// to silently skip entries whose key or value cannot be cast;
+ /// otherwise, to throw an .
+ ///
+ /// A new strongly-typed dictionary containing the converted entries.
+ ///
+ /// is and an entry's key or value
+ /// cannot be cast to the target type.
+ ///
public static IDictionary ToDictionary(this IDictionary dictionary,
bool skipNotMatchingEntries)
{
@@ -64,6 +109,24 @@ public static IDictionary ToDictionary(this IDiction
return convertedDictionary;
}
+ ///
+ /// Converts a non-generic to a strongly-typed
+ /// by casting each key and transforming each value
+ /// with the specified selector.
+ ///
+ /// The target key type.
+ /// The target value type.
+ /// The non-generic dictionary to convert.
+ /// The function that transforms each raw value into .
+ ///
+ /// to silently skip entries whose key cannot be cast;
+ /// otherwise, to throw an .
+ ///
+ /// A new strongly-typed dictionary containing the converted entries.
+ ///
+ /// is and an entry's key
+ /// cannot be cast to .
+ ///
public static IDictionary ToDictionary(this IDictionary dictionary,
Func