diff --git a/src/SenseNet.Tools.Tests/SnTraceTests.cs b/src/SenseNet.Tools.Tests/SnTraceTests.cs index 0ebae8a..6700278 100644 --- a/src/SenseNet.Tools.Tests/SnTraceTests.cs +++ b/src/SenseNet.Tools.Tests/SnTraceTests.cs @@ -12,7 +12,7 @@ namespace SenseNet.Tools.Tests { [TestClass] public class SnTraceTests : SnTraceTestClass - { + { [ClassInitialize] public static void InitializeTracers(TestContext context) { @@ -482,15 +482,20 @@ public void SnTrace_ToTrace_Array_String() public void SnTrace_ToTrace_Dictionary_StringString() { Dictionary d1 = null; - var d2 = new Dictionary() + var d2 = new Dictionary { { "key1", null }, { "key2", "value2" }, { "key3", "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong" }, + { "key4", "value4" }, + { "key5", "value5" }, + { "key6", "value6" }, }; Assert.AreEqual(string.Empty, d1.ToTrace()); - Assert.AreEqual("key1: {null}, key2: value2 (6), key3: looooooooooooooooooo... (77)", d2.ToTrace()); + Assert.AreEqual( + "key1:{null}, key2:value2, key3:looooooooooooooooooo...(77), key4:value4, ... (total count: 6)", + d2.ToTrace(4)); } } } diff --git a/src/SenseNet.Tools/Configuration/OptionsClassAttribute.cs b/src/SenseNet.Tools/Configuration/OptionsClassAttribute.cs index 3423d78..ca67778 100644 --- a/src/SenseNet.Tools/Configuration/OptionsClassAttribute.cs +++ b/src/SenseNet.Tools/Configuration/OptionsClassAttribute.cs @@ -2,11 +2,25 @@ namespace SenseNet.Tools.Configuration; +/// +/// Marker attribute for sensenet options classes. +/// [AttributeUsage(AttributeTargets.Class, Inherited = false)] public class OptionsClassAttribute : Attribute { + /// + /// Gets the section path e.g. "mainsection:subsection" + /// public string SectionName { get; } + /// + /// Initializes a new instance of the class. + /// + /// + /// The parameter is for documentation purposes only, + /// it is not used for binding. + /// + /// Path of the section e.g. "mainsection:subsection". public OptionsClassAttribute(string sectionName) { SectionName = sectionName; diff --git a/src/SenseNet.Tools/Diagnostics/LoggerExtensions.cs b/src/SenseNet.Tools/Diagnostics/LoggerExtensions.cs index 71de140..f8980c7 100644 --- a/src/SenseNet.Tools/Diagnostics/LoggerExtensions.cs +++ b/src/SenseNet.Tools/Diagnostics/LoggerExtensions.cs @@ -6,7 +6,9 @@ // ReSharper disable once CheckNamespace namespace SenseNet.Extensions.DependencyInjection { +#pragma warning disable CS1591 public static class LoggerExtensions +#pragma warning restore CS1591 { /// /// Routes all log and trace messages to the official .Net ILogger interface. diff --git a/src/SenseNet.Tools/Diagnostics/SnILogger.cs b/src/SenseNet.Tools/Diagnostics/SnILogger.cs index 4478599..da2816c 100644 --- a/src/SenseNet.Tools/Diagnostics/SnILogger.cs +++ b/src/SenseNet.Tools/Diagnostics/SnILogger.cs @@ -11,11 +11,17 @@ namespace SenseNet.Diagnostics public class SnILogger : SnEventloggerBase { private readonly ILogger _logger; + + /// + /// Initializes a new instance of the class. + /// + /// Target logger service public SnILogger(ILogger logger) { _logger = logger; } + /// protected override void WriteEntry(string entry, EventLogEntryType entryType, int eventId) { switch (entryType) diff --git a/src/SenseNet.Tools/Diagnostics/SnILoggerTracer.cs b/src/SenseNet.Tools/Diagnostics/SnILoggerTracer.cs index f9b335b..a2bc95d 100644 --- a/src/SenseNet.Tools/Diagnostics/SnILoggerTracer.cs +++ b/src/SenseNet.Tools/Diagnostics/SnILoggerTracer.cs @@ -9,16 +9,23 @@ namespace SenseNet.Diagnostics public class SnILoggerTracer : ISnTracer { private readonly ILogger _logger; + + /// + /// Initializes a new instance of the class. + /// + /// Target logger service public SnILoggerTracer(ILogger logger) { _logger = logger; } + /// public void Write(string line) { _logger?.LogTrace(line); } + /// public void Flush() { // do nothing diff --git a/src/SenseNet.Tools/Diagnostics/SnTraceExtensions.cs b/src/SenseNet.Tools/Diagnostics/SnTraceExtensions.cs index 917b5c3..276f903 100644 --- a/src/SenseNet.Tools/Diagnostics/SnTraceExtensions.cs +++ b/src/SenseNet.Tools/Diagnostics/SnTraceExtensions.cs @@ -4,8 +4,16 @@ // ReSharper disable once CheckNamespace namespace SenseNet.Diagnostics { +#pragma warning disable CS1591 public static class SnTraceExtensions +#pragma warning restore CS1591 { + /// + /// Generates a limited length trace message from a string data. + /// + /// Source data. + /// Optional cutoff limit. Default: 100. + /// public static string ToTrace(this string text, int maxLength = 100) { if (string.IsNullOrEmpty(text)) @@ -14,27 +22,49 @@ public static string ToTrace(this string text, int maxLength = 100) return text.Length < maxLength ? text : text.Substring(0, maxLength); } + /// + /// Generates a limited length trace message from a set of integers. + /// + /// Source data. + /// Optional cutoff limit. Default: 32. + /// public static string ToTrace(this IEnumerable items, int maxCount = 32) => items == null ? string.Empty : Format(items.Take(maxCount + 1).Select(x => x.ToString()).ToArray(), maxCount); + /// + /// Generates a limited length trace message from a set of strings. + /// + /// Source data. + /// Optional cutoff limit. Default: 10. + /// public static string ToTrace(this IEnumerable items, int maxCount = 10) => items == null ? string.Empty : Format(items.Take(maxCount + 1).ToArray(), maxCount); - public static string ToTrace(this IDictionary data) + /// + /// Generates a trace message from max items of a IDictionary<string, string> int the following format: "key1: value1, key2: value2". + /// if an item value length is greater than 20 it is cut off and the original length is written: "very long text very long...(78)" + /// + /// Source data. + /// Optional cutoff limit. Default: 10. + /// + public static string ToTrace(this IDictionary data, int maxCount = 10) { if (data == null) return string.Empty; - return string.Join(", ", data.Select(x => + var moreItems = data.Count > maxCount ? $", ... (total count: {data.Count})" : string.Empty; + + return string.Join(", ", data.Take(maxCount).Select(x => { if (x.Value == null) - return $"{x.Key}: {{null}}"; - return $"{x.Key}: " + - $"{(x.Value.Length > 20 ? x.Value.Substring(0, 20) + "..." : x.Value)} " + - $"({x.Value.Length})"; - })); + return $"{x.Key}:{{null}}"; + var lenghtString = x.Value.Length > 20 ? $"({x.Value.Length})" : string.Empty; + return $"{x.Key}:" + + $"{(x.Value.Length > 20 ? x.Value.Substring(0, 20) + "..." : x.Value)}" + + lenghtString; + })) + moreItems; } private static string Format(string[] set, int maxCount) => diff --git a/src/SenseNet.Tools/Features/FeatureAvailability.cs b/src/SenseNet.Tools/Features/FeatureAvailability.cs index 3959c26..0619ed0 100644 --- a/src/SenseNet.Tools/Features/FeatureAvailability.cs +++ b/src/SenseNet.Tools/Features/FeatureAvailability.cs @@ -7,10 +7,15 @@ namespace SenseNet.Tools.Features; /// public enum FeatureState { + /// Default state. Unknown, + /// The feature is available and working. Active, + /// The feature is switched off globally. Disabled, + /// The feature is enabled but it is not configured correctly. NotConfigured, + /// The current user does not have sufficient permissions to use this feature. Unavailable } @@ -19,6 +24,12 @@ public enum FeatureState /// public record FeatureAvailability { + /// + /// Initializes a new instance of the class. + /// + /// + /// + /// public FeatureAvailability(FeatureState state, string reason = null, DateTime lastAvailable = default) { State = state; diff --git a/src/SenseNet.Tools/Features/FeaturesExtensions.cs b/src/SenseNet.Tools/Features/FeaturesExtensions.cs index 59cb8e6..5d9ee96 100644 --- a/src/SenseNet.Tools/Features/FeaturesExtensions.cs +++ b/src/SenseNet.Tools/Features/FeaturesExtensions.cs @@ -4,7 +4,9 @@ // ReSharper disable once CheckNamespace namespace SenseNet.Extensions.DependencyInjection; +#pragma warning disable CS1591 public static class FeaturesExtensions +#pragma warning restore CS1591 { /// /// Adds a feature to the service collection. diff --git a/src/SenseNet.Tools/SenseNet.Tools.csproj b/src/SenseNet.Tools/SenseNet.Tools.csproj index d39b34b..249342c 100644 --- a/src/SenseNet.Tools/SenseNet.Tools.csproj +++ b/src/SenseNet.Tools/SenseNet.Tools.csproj @@ -26,6 +26,7 @@ true true snupkg + True diff --git a/src/SenseNet.Tools/Testing/ObjectAccessor.cs b/src/SenseNet.Tools/Testing/ObjectAccessor.cs index ef146e6..ae9fad9 100644 --- a/src/SenseNet.Tools/Testing/ObjectAccessor.cs +++ b/src/SenseNet.Tools/Testing/ObjectAccessor.cs @@ -15,6 +15,9 @@ public class ObjectAccessor private BindingFlags _publicFlags = BindingFlags.Instance | BindingFlags.Public; private BindingFlags _privateFlags = BindingFlags.Instance | BindingFlags.NonPublic; + /// + /// Gets the wrapped object. + /// public object Target { get; } /// diff --git a/src/SenseNet.Tools/Tools/Retrier/DefaultRetrier.cs b/src/SenseNet.Tools/Tools/Retrier/DefaultRetrier.cs index 7561022..1b35bef 100644 --- a/src/SenseNet.Tools/Tools/Retrier/DefaultRetrier.cs +++ b/src/SenseNet.Tools/Tools/Retrier/DefaultRetrier.cs @@ -13,12 +13,18 @@ public class DefaultRetrier : IRetrier private readonly ILogger _logger; private readonly RetrierOptions _options; + /// + /// Initializes a new instance of the class. + /// + /// Configuration object. + /// Logger service. public DefaultRetrier(IOptions options, ILogger logger) { _logger = logger; _options = options.Value; } + /// public Task RetryAsync(Func action, Func shouldRetry = null, Func shouldRetryOnError = null, Action onAfterLastIteration = null, @@ -28,6 +34,7 @@ public Task RetryAsync(Func action, Func shouldRetry = null, onAfterLastIteration, cancel); } + /// public Task RetryAsync(Func> action, Func shouldRetry = null, Func shouldRetryOnError = null, Action onAfterLastIteration = null, @@ -37,6 +44,7 @@ public Task RetryAsync(Func> action, Func shouldRetr onAfterLastIteration, cancel); } + /// public Task RetryAsync(int count, int waitMilliseconds, Func action, Func shouldRetry = null, Func shouldRetryOnError = null, Action onAfterLastIteration = null, CancellationToken cancel = default) @@ -60,6 +68,7 @@ public Task RetryAsync(int count, int waitMilliseconds, Func action, Func< cancel: cancel); } + /// public Task RetryAsync(int count, int waitMilliseconds, Func> action, Func shouldRetry = null, Func shouldRetryOnError = null, Action onAfterLastIteration = null, diff --git a/src/SenseNet.Tools/Tools/Retrier/RetrierOptions.cs b/src/SenseNet.Tools/Tools/Retrier/RetrierOptions.cs index 40cf86f..aed887a 100644 --- a/src/SenseNet.Tools/Tools/Retrier/RetrierOptions.cs +++ b/src/SenseNet.Tools/Tools/Retrier/RetrierOptions.cs @@ -3,9 +3,20 @@ // ReSharper disable once CheckNamespace namespace SenseNet.Tools; +/// +/// Configuration values for the Retrier feature. +/// All properties have default values, none of them is mandatory. +/// [OptionsClass(sectionName: "sensenet:Retrier")] public class RetrierOptions { + /// + /// Gets or sets how many times an operation is retried if the caller + /// did not provide a different value. Default: 10. + /// public int Count { get; set; } = 10; + /// + /// Gets or sets how many milliseconds will the module wait between two attempts. Default: 1000. + /// public int WaitMilliseconds { get; set; } = 1000; } \ No newline at end of file diff --git a/src/SenseNet.Tools/Tools/ToolsExtensions.cs b/src/SenseNet.Tools/Tools/ToolsExtensions.cs index d200cf8..9785e24 100644 --- a/src/SenseNet.Tools/Tools/ToolsExtensions.cs +++ b/src/SenseNet.Tools/Tools/ToolsExtensions.cs @@ -5,7 +5,9 @@ // ReSharper disable once CheckNamespace namespace SenseNet.Extensions.DependencyInjection { +#pragma warning disable CS1591 public static class ToolsExtensions +#pragma warning restore CS1591 { /// /// Adds the default retrier to the service collection.