From 2481a95f71674eeee05e20f4cf4e2f116effeeb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Luis=20Barreda=20G=C3=BCere=C3=B1a?= Date: Fri, 10 Oct 2025 01:43:03 -0700 Subject: [PATCH 1/6] feat: add validation, logging, and type utilities Added new extensions for argument validation, logging, and type utilities. Introduced `NumberBaseExtensions`, `StringExtensions`, `TimeProviderExtensions`, and `TypeExtensions` with methods for validation, formatting, and conversions. Enhanced documentation and added comprehensive tests for all new features. ### Key Changes: - `NumberBaseExtensions`: Added methods like `ThrowIfNegative`, `ThrowIfZero`, etc. - `StringExtensions`: Added methods like `IsNotNull`, `ThrowIfNullOrEmpty`, etc. - `TimeProviderExtensions`: Added methods like `Freeze`, `GetUtcNowAsDateTime`, etc. - `TypeExtensions`: Added methods like `GetTypeName`, `IsIEnumerableOfT`, etc. - Added `BuiltInTypeAliasMap` for C# keyword aliases. - Comprehensive documentation updates and new tests for all methods. --- Directory.Build.props | 6 +- docs/api/DevElf.Benchmarks/README.md | 3 + docs/api/DevElf.Logging/DevElf.Logging.md | 14 + ...ChangeEventId.2II91DHU6UBPX38ZVB3F7A973.md | 17 + ...hangeLogLevel.T8V2CVT94S8T3JEG5QV4IHR23.md | 17 + ...ChangeMessage.2FDKFV78GR308BJBSTOALKPQ1.md | 17 + ....SetException.RD4VYIJ1SQ9EVWX51XVKJSNO7.md | 23 + ...e.SetProperty.W33WIH8SSDTY69PIOC9JED2Q2.md | 35 + docs/api/DevElf.Logging/ILogMessageScope.md | 21 + .../ILogMessageScopeAccessor.Current.md | 14 + .../ILogMessageScopeAccessor.md | 17 + .../LogMessageScopeAccessor.Current.md | 16 + .../DevElf.Logging/LogMessageScopeAccessor.md | 18 + .../LoggerExtensions.BeginMessageScope.md | 169 +++++ docs/api/DevElf.Logging/LoggerExtensions.md | 19 + docs/api/DevElf.Logging/README.md | 7 + ...MessageScopes.GDXEN2I4SIKZ4272TRDXESVJ4.md | 21 + .../ServiceCollectionExtensions.md | 16 + ...ComparableExtensions.ThrowIfGreaterThan.md | 179 +++++ ...eExtensions.ThrowIfGreaterThanOrEqualTo.md | 179 +++++ .../ComparableExtensions.ThrowIfLessThan.md | 179 +++++ ...ableExtensions.ThrowIfLessThanOrEqualTo.md | 179 +++++ docs/api/DevElf/ComparableExtensions.md | 31 + ...DayAsTimeOnly.3V6AA5YCYRJVWJ22EJ3V4M9HB.md | 18 + ...DayAsTimeOnly.LV829LH80XT0GJ710EA0YJF1A.md | 19 + ...ns.ToDateOnly.5DJTI5YJCKDCRWGSCHQA5JOD1.md | 19 + ...LocalDateOnly.9MOVTIQPSF8VLKP71YIJ9VH0F.md | 18 + ...ToUtcDateOnly.8GHFUS2T4LHILJG3WKPW3KX85.md | 18 + docs/api/DevElf/DateTimeOffsetExtensions.md | 20 + docs/api/DevElf/DevElf.ArgumentValidation.md | 13 + docs/api/DevElf/DevElf.Extensions.md | 14 + docs/api/DevElf/DevElf.md | 7 + ...ons.IsDefined.0N6AKTCYCMQW0BJOS1GLOX8Q9.md | 29 + ....IsNotDefined.RY2DLHY3SWCK2LPWGAEY4HEMA.md | 29 + ...wIfNotDefined.OUB1Y4FPQFP2H9KPNZ3994UB8.md | 38 + docs/api/DevElf/EnumExtensions.md | 16 + ...sions.IsEmpty.G3EUDQ6V6NURF5GQ19WB5WJ1B.md | 34 + ...ns.IsNotEmpty.YHWIUF0FBFXTBPAJA3GTXT912.md | 34 + ...otNullOrEmpty.IC9LTCW13TGHLKM4O0YNM0V96.md | 30 + ...IsNullOrEmpty.L8EM3HR11BCX0GSI8EE8Q05H6.md | 30 + ...wIfNullOrEmpty.HOGY2PMFWW387IVPL7H586RR.md | 41 ++ docs/api/DevElf/EnumerableExtensions.md | 17 + .../EquatableExtensions.ThrowIfEqual.md | 183 +++++ .../EquatableExtensions.ThrowIfNotEqual.md | 183 +++++ docs/api/DevElf/EquatableExtensions.md | 23 + .../FrozenTimeProvider.FrozenTimeProvider.md | 50 ++ .../DevElf/FrozenTimeProvider.GetUtcNow().md | 14 + docs/api/DevElf/FrozenTimeProvider.md | 22 + .../DevElf/GenericExtensions.ThrowIfNull.md | 87 +++ docs/api/DevElf/GenericExtensions.md | 17 + .../LambdaExtensions.UnwrapAndReThrow.md | 74 ++ docs/api/DevElf/LambdaExtensions.md | 17 + .../NumberBaseExtensions.ThrowIfNegative.md | 83 +++ ...berBaseExtensions.ThrowIfNegativeOrZero.md | 83 +++ .../NumberBaseExtensions.ThrowIfPositive.md | 83 +++ .../NumberBaseExtensions.ThrowIfZero.md | 83 +++ docs/api/DevElf/NumberBaseExtensions.md | 23 + docs/api/DevElf/README.md | 9 + ...ons.IsNotNull.GOG4FDWMXCHP33679EC3INILB.md | 23 + ...otNullOrEmpty.KOMZAKBYLVXEEOD08YGARAPM4.md | 23 + ...lOrWhiteSpace.9919O1K4JIH04407ZF15FU221.md | 24 + ...nsions.IsNull.9K7FPD1SVNHTXA9PG00T6WJB7.md | 22 + ...IsNullOrEmpty.83A6J6VCAV38Q1YDNQBEEPYKB.md | 23 + ...lOrWhiteSpace.TPNVX18CCNJW0BW0NI3QBH3X1.md | 23 + ...IfNullOrEmpty.D8P8RJ38QN1GJYOQY7V7DCNDC.md | 31 + ...lOrWhiteSpace.WMBRDAXWAI57LA4GBGL662203.md | 35 + docs/api/DevElf/StringExtensions.md | 17 + ...nsions.Freeze.JJKQRV3GO414APBG2SPV9FKV1.md | 26 + ...NowAsDateTime.M84J6LMDXEKC4KGHO8DWP8HO4.md | 26 + ....GetTimeOfDay.BZQPKC1HDAVIWAAQUAOFRTGA1.md | 26 + ...ions.GetToday.ZV4BS2Q217E0OPUMVKLSXRLHE.md | 26 + ...NowAsDateTime.G3U2UI7C7M6TWL6JEY3ZC6PX3.md | 26 + ...tUtcTimeOfDay.BGDOQDAMLTGGQQS14AWAESZF6.md | 26 + ...s.GetUtcToday.8SIFE92OI2ICNT916X4QAWNY7.md | 26 + docs/api/DevElf/TimeProviderExtensions.md | 22 + ...dTypeFullName.P76O9STWHPAGRI25QVIUQ5MVD.md | 35 + ...attedTypeName.IAF1XPCUI7NL3R5U5999O4SM4.md | 42 ++ ...yTypeFullName.TGDWG5RWDUJW2KUFF1GSUH52B.md | 24 + ...endlyTypeName.J35G2Y7DEMNMKUW3HYFEJQRE4.md | 30 + ...ricParameters.W1YHOUP03743XOTR3ULZTUPA6.md | 22 + ...s.GetTypeName.UH859SB3JKYGI29AZPHHWSOT5.md | 28 + ...EnumerableOfT.94FI3DNSKIQR77KQEYY3O9VJ6.md | 30 + ...ions.IsStatic.3K24BJS6E9QC8MFS6MLNUI3FA.md | 22 + ...erableOfTType.0M5ESH17YJABIKN8X3RLK96BC.md | 37 + ...EnumerableOfT.W0NGC76YSUAP62VXD2CX03CT1.md | 37 + ...2A8C577E514BE40E3DD.BuiltInTypeAliasMap.md | 13 + ...ns._G_$6B6159A298CA62A8C577E514BE40E3DD.md | 14 + ...ypeExtensions.get_BuiltInTypeAliasMap().md | 13 + docs/api/DevElf/TypeExtensions.md | 27 + src/DevElf.Logging/LogMessageScope.cs | 4 +- src/DevElf/Extensions/TypeExtensions.cs | 324 ++++++++ .../Extensions/TypeExtensionsTests.cs | 692 ++++++++++++++++++ 92 files changed, 4489 insertions(+), 5 deletions(-) create mode 100644 docs/api/DevElf.Benchmarks/README.md create mode 100644 docs/api/DevElf.Logging/DevElf.Logging.md create mode 100644 docs/api/DevElf.Logging/ILogMessageScope.ChangeEventId.2II91DHU6UBPX38ZVB3F7A973.md create mode 100644 docs/api/DevElf.Logging/ILogMessageScope.ChangeLogLevel.T8V2CVT94S8T3JEG5QV4IHR23.md create mode 100644 docs/api/DevElf.Logging/ILogMessageScope.ChangeMessage.2FDKFV78GR308BJBSTOALKPQ1.md create mode 100644 docs/api/DevElf.Logging/ILogMessageScope.SetException.RD4VYIJ1SQ9EVWX51XVKJSNO7.md create mode 100644 docs/api/DevElf.Logging/ILogMessageScope.SetProperty.W33WIH8SSDTY69PIOC9JED2Q2.md create mode 100644 docs/api/DevElf.Logging/ILogMessageScope.md create mode 100644 docs/api/DevElf.Logging/ILogMessageScopeAccessor.Current.md create mode 100644 docs/api/DevElf.Logging/ILogMessageScopeAccessor.md create mode 100644 docs/api/DevElf.Logging/LogMessageScopeAccessor.Current.md create mode 100644 docs/api/DevElf.Logging/LogMessageScopeAccessor.md create mode 100644 docs/api/DevElf.Logging/LoggerExtensions.BeginMessageScope.md create mode 100644 docs/api/DevElf.Logging/LoggerExtensions.md create mode 100644 docs/api/DevElf.Logging/README.md create mode 100644 docs/api/DevElf.Logging/ServiceCollectionExtensions.AddLogMessageScopes.GDXEN2I4SIKZ4272TRDXESVJ4.md create mode 100644 docs/api/DevElf.Logging/ServiceCollectionExtensions.md create mode 100644 docs/api/DevElf/ComparableExtensions.ThrowIfGreaterThan.md create mode 100644 docs/api/DevElf/ComparableExtensions.ThrowIfGreaterThanOrEqualTo.md create mode 100644 docs/api/DevElf/ComparableExtensions.ThrowIfLessThan.md create mode 100644 docs/api/DevElf/ComparableExtensions.ThrowIfLessThanOrEqualTo.md create mode 100644 docs/api/DevElf/ComparableExtensions.md create mode 100644 docs/api/DevElf/DateTimeOffsetExtensions.LocalTimeOfDayAsTimeOnly.3V6AA5YCYRJVWJ22EJ3V4M9HB.md create mode 100644 docs/api/DevElf/DateTimeOffsetExtensions.TimeOfDayAsTimeOnly.LV829LH80XT0GJ710EA0YJF1A.md create mode 100644 docs/api/DevElf/DateTimeOffsetExtensions.ToDateOnly.5DJTI5YJCKDCRWGSCHQA5JOD1.md create mode 100644 docs/api/DevElf/DateTimeOffsetExtensions.ToLocalDateOnly.9MOVTIQPSF8VLKP71YIJ9VH0F.md create mode 100644 docs/api/DevElf/DateTimeOffsetExtensions.ToUtcDateOnly.8GHFUS2T4LHILJG3WKPW3KX85.md create mode 100644 docs/api/DevElf/DateTimeOffsetExtensions.md create mode 100644 docs/api/DevElf/DevElf.ArgumentValidation.md create mode 100644 docs/api/DevElf/DevElf.Extensions.md create mode 100644 docs/api/DevElf/DevElf.md create mode 100644 docs/api/DevElf/EnumExtensions.IsDefined.0N6AKTCYCMQW0BJOS1GLOX8Q9.md create mode 100644 docs/api/DevElf/EnumExtensions.IsNotDefined.RY2DLHY3SWCK2LPWGAEY4HEMA.md create mode 100644 docs/api/DevElf/EnumExtensions.ThrowIfNotDefined.OUB1Y4FPQFP2H9KPNZ3994UB8.md create mode 100644 docs/api/DevElf/EnumExtensions.md create mode 100644 docs/api/DevElf/EnumerableExtensions.IsEmpty.G3EUDQ6V6NURF5GQ19WB5WJ1B.md create mode 100644 docs/api/DevElf/EnumerableExtensions.IsNotEmpty.YHWIUF0FBFXTBPAJA3GTXT912.md create mode 100644 docs/api/DevElf/EnumerableExtensions.IsNotNullOrEmpty.IC9LTCW13TGHLKM4O0YNM0V96.md create mode 100644 docs/api/DevElf/EnumerableExtensions.IsNullOrEmpty.L8EM3HR11BCX0GSI8EE8Q05H6.md create mode 100644 docs/api/DevElf/EnumerableExtensions.ThrowIfNullOrEmpty.HOGY2PMFWW387IVPL7H586RR.md create mode 100644 docs/api/DevElf/EnumerableExtensions.md create mode 100644 docs/api/DevElf/EquatableExtensions.ThrowIfEqual.md create mode 100644 docs/api/DevElf/EquatableExtensions.ThrowIfNotEqual.md create mode 100644 docs/api/DevElf/EquatableExtensions.md create mode 100644 docs/api/DevElf/FrozenTimeProvider.FrozenTimeProvider.md create mode 100644 docs/api/DevElf/FrozenTimeProvider.GetUtcNow().md create mode 100644 docs/api/DevElf/FrozenTimeProvider.md create mode 100644 docs/api/DevElf/GenericExtensions.ThrowIfNull.md create mode 100644 docs/api/DevElf/GenericExtensions.md create mode 100644 docs/api/DevElf/LambdaExtensions.UnwrapAndReThrow.md create mode 100644 docs/api/DevElf/LambdaExtensions.md create mode 100644 docs/api/DevElf/NumberBaseExtensions.ThrowIfNegative.md create mode 100644 docs/api/DevElf/NumberBaseExtensions.ThrowIfNegativeOrZero.md create mode 100644 docs/api/DevElf/NumberBaseExtensions.ThrowIfPositive.md create mode 100644 docs/api/DevElf/NumberBaseExtensions.ThrowIfZero.md create mode 100644 docs/api/DevElf/NumberBaseExtensions.md create mode 100644 docs/api/DevElf/README.md create mode 100644 docs/api/DevElf/StringExtensions.IsNotNull.GOG4FDWMXCHP33679EC3INILB.md create mode 100644 docs/api/DevElf/StringExtensions.IsNotNullOrEmpty.KOMZAKBYLVXEEOD08YGARAPM4.md create mode 100644 docs/api/DevElf/StringExtensions.IsNotNullOrWhiteSpace.9919O1K4JIH04407ZF15FU221.md create mode 100644 docs/api/DevElf/StringExtensions.IsNull.9K7FPD1SVNHTXA9PG00T6WJB7.md create mode 100644 docs/api/DevElf/StringExtensions.IsNullOrEmpty.83A6J6VCAV38Q1YDNQBEEPYKB.md create mode 100644 docs/api/DevElf/StringExtensions.IsNullOrWhiteSpace.TPNVX18CCNJW0BW0NI3QBH3X1.md create mode 100644 docs/api/DevElf/StringExtensions.ThrowIfNullOrEmpty.D8P8RJ38QN1GJYOQY7V7DCNDC.md create mode 100644 docs/api/DevElf/StringExtensions.ThrowIfNullOrWhiteSpace.WMBRDAXWAI57LA4GBGL662203.md create mode 100644 docs/api/DevElf/StringExtensions.md create mode 100644 docs/api/DevElf/TimeProviderExtensions.Freeze.JJKQRV3GO414APBG2SPV9FKV1.md create mode 100644 docs/api/DevElf/TimeProviderExtensions.GetLocalNowAsDateTime.M84J6LMDXEKC4KGHO8DWP8HO4.md create mode 100644 docs/api/DevElf/TimeProviderExtensions.GetTimeOfDay.BZQPKC1HDAVIWAAQUAOFRTGA1.md create mode 100644 docs/api/DevElf/TimeProviderExtensions.GetToday.ZV4BS2Q217E0OPUMVKLSXRLHE.md create mode 100644 docs/api/DevElf/TimeProviderExtensions.GetUtcNowAsDateTime.G3U2UI7C7M6TWL6JEY3ZC6PX3.md create mode 100644 docs/api/DevElf/TimeProviderExtensions.GetUtcTimeOfDay.BGDOQDAMLTGGQQS14AWAESZF6.md create mode 100644 docs/api/DevElf/TimeProviderExtensions.GetUtcToday.8SIFE92OI2ICNT916X4QAWNY7.md create mode 100644 docs/api/DevElf/TimeProviderExtensions.md create mode 100644 docs/api/DevElf/TypeExtensions.GetCustomFormattedTypeFullName.P76O9STWHPAGRI25QVIUQ5MVD.md create mode 100644 docs/api/DevElf/TypeExtensions.GetCustomFormattedTypeName.IAF1XPCUI7NL3R5U5999O4SM4.md create mode 100644 docs/api/DevElf/TypeExtensions.GetFriendlyTypeFullName.TGDWG5RWDUJW2KUFF1GSUH52B.md create mode 100644 docs/api/DevElf/TypeExtensions.GetFriendlyTypeName.J35G2Y7DEMNMKUW3HYFEJQRE4.md create mode 100644 docs/api/DevElf/TypeExtensions.GetNameWithoutGenericParameters.W1YHOUP03743XOTR3ULZTUPA6.md create mode 100644 docs/api/DevElf/TypeExtensions.GetTypeName.UH859SB3JKYGI29AZPHHWSOT5.md create mode 100644 docs/api/DevElf/TypeExtensions.IsIEnumerableOfT.94FI3DNSKIQR77KQEYY3O9VJ6.md create mode 100644 docs/api/DevElf/TypeExtensions.IsStatic.3K24BJS6E9QC8MFS6MLNUI3FA.md create mode 100644 docs/api/DevElf/TypeExtensions.TryGetIEnumerableOfTType.0M5ESH17YJABIKN8X3RLK96BC.md create mode 100644 docs/api/DevElf/TypeExtensions.TryGetTypeOfTFromIEnumerableOfT.W0NGC76YSUAP62VXD2CX03CT1.md create mode 100644 docs/api/DevElf/TypeExtensions._G_$6B6159A298CA62A8C577E514BE40E3DD.BuiltInTypeAliasMap.md create mode 100644 docs/api/DevElf/TypeExtensions._G_$6B6159A298CA62A8C577E514BE40E3DD.md create mode 100644 docs/api/DevElf/TypeExtensions.get_BuiltInTypeAliasMap().md create mode 100644 docs/api/DevElf/TypeExtensions.md create mode 100644 src/DevElf/Extensions/TypeExtensions.cs create mode 100644 tests/DevElf.Tests/Extensions/TypeExtensionsTests.cs diff --git a/Directory.Build.props b/Directory.Build.props index 614f870..f769fdb 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -2,7 +2,7 @@ net10.0 - latest + 14 $(MSBuildProjectName.Replace(" ", "_")) enable enable @@ -30,8 +30,8 @@ package source defined in your configuration. We don't get this warning because we're using source mapping, but we still disable it just to play it safe. --> - + true + $(NoWarn),1573,1591,1712,NU1507 diff --git a/docs/api/DevElf.Benchmarks/README.md b/docs/api/DevElf.Benchmarks/README.md new file mode 100644 index 0000000..fbe524d --- /dev/null +++ b/docs/api/DevElf.Benchmarks/README.md @@ -0,0 +1,3 @@ +#### [DevElf\.Benchmarks](README.md 'README') + +## DevElf\.Benchmarks Assembly \ No newline at end of file diff --git a/docs/api/DevElf.Logging/DevElf.Logging.md b/docs/api/DevElf.Logging/DevElf.Logging.md new file mode 100644 index 0000000..bdc9a75 --- /dev/null +++ b/docs/api/DevElf.Logging/DevElf.Logging.md @@ -0,0 +1,14 @@ +#### [DevElf\.Logging](README.md 'README') + +## DevElf\.Logging Namespace + +| Classes | | +| :--- | :--- | +| [LoggerExtensions](LoggerExtensions.md 'DevElf\.Logging\.LoggerExtensions') | Extension methods for [Microsoft\.Extensions\.Logging\.ILogger](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.ilogger 'Microsoft\.Extensions\.Logging\.ILogger') to integrate with [DevElf\.Logging\.LogMessageScope](https://learn.microsoft.com/en-us/dotnet/api/develf.logging.logmessagescope 'DevElf\.Logging\.LogMessageScope')\. | +| [LogMessageScopeAccessor](LogMessageScopeAccessor.md 'DevElf\.Logging\.LogMessageScopeAccessor') | Provides access to the current [log message scope](https://learn.microsoft.com/en-us/dotnet/api/develf.logging.logmessagescope 'DevElf\.Logging\.LogMessageScope')\. | +| [ServiceCollectionExtensions](ServiceCollectionExtensions.md 'DevElf\.Logging\.ServiceCollectionExtensions') | Extension methods for configuring log message scope services in dependency injection\. | + +| Interfaces | | +| :--- | :--- | +| [ILogMessageScope](ILogMessageScope.md 'DevElf\.Logging\.ILogMessageScope') | Represents an ambient log message scope\. Implementations buffer properties and emit a log entry on [System\.IDisposable\.Dispose](https://learn.microsoft.com/en-us/dotnet/api/system.idisposable.dispose 'System\.IDisposable\.Dispose')\. | +| [ILogMessageScopeAccessor](ILogMessageScopeAccessor.md 'DevElf\.Logging\.ILogMessageScopeAccessor') | Provides access to the current [ILogMessageScope](ILogMessageScope.md 'DevElf\.Logging\.ILogMessageScope')\. | diff --git a/docs/api/DevElf.Logging/ILogMessageScope.ChangeEventId.2II91DHU6UBPX38ZVB3F7A973.md b/docs/api/DevElf.Logging/ILogMessageScope.ChangeEventId.2II91DHU6UBPX38ZVB3F7A973.md new file mode 100644 index 0000000..0300eab --- /dev/null +++ b/docs/api/DevElf.Logging/ILogMessageScope.ChangeEventId.2II91DHU6UBPX38ZVB3F7A973.md @@ -0,0 +1,17 @@ +#### [DevElf\.Logging](README.md 'README') +### [DevElf\.Logging](DevElf.Logging.md 'DevElf\.Logging').[ILogMessageScope](ILogMessageScope.md 'DevElf\.Logging\.ILogMessageScope') + +## ILogMessageScope\.ChangeEventId\(EventId\) Method + +Changes the [Microsoft\.Extensions\.Logging\.EventId](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.eventid 'Microsoft\.Extensions\.Logging\.EventId') that will be used when this scope emits its log entry on dispose\. + +```csharp +void ChangeEventId(Microsoft.Extensions.Logging.EventId eventId); +``` +#### Parameters + + + +`eventId` [Microsoft\.Extensions\.Logging\.EventId](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.eventid 'Microsoft\.Extensions\.Logging\.EventId') + +The new event identifier\. \ No newline at end of file diff --git a/docs/api/DevElf.Logging/ILogMessageScope.ChangeLogLevel.T8V2CVT94S8T3JEG5QV4IHR23.md b/docs/api/DevElf.Logging/ILogMessageScope.ChangeLogLevel.T8V2CVT94S8T3JEG5QV4IHR23.md new file mode 100644 index 0000000..5aeac23 --- /dev/null +++ b/docs/api/DevElf.Logging/ILogMessageScope.ChangeLogLevel.T8V2CVT94S8T3JEG5QV4IHR23.md @@ -0,0 +1,17 @@ +#### [DevElf\.Logging](README.md 'README') +### [DevElf\.Logging](DevElf.Logging.md 'DevElf\.Logging').[ILogMessageScope](ILogMessageScope.md 'DevElf\.Logging\.ILogMessageScope') + +## ILogMessageScope\.ChangeLogLevel\(LogLevel\) Method + +Changes the log level that will be used when this scope emits its log entry on dispose\. + +```csharp +void ChangeLogLevel(Microsoft.Extensions.Logging.LogLevel logLevel); +``` +#### Parameters + + + +`logLevel` [Microsoft\.Extensions\.Logging\.LogLevel](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.loglevel 'Microsoft\.Extensions\.Logging\.LogLevel') + +The new log level\. \ No newline at end of file diff --git a/docs/api/DevElf.Logging/ILogMessageScope.ChangeMessage.2FDKFV78GR308BJBSTOALKPQ1.md b/docs/api/DevElf.Logging/ILogMessageScope.ChangeMessage.2FDKFV78GR308BJBSTOALKPQ1.md new file mode 100644 index 0000000..d68ba24 --- /dev/null +++ b/docs/api/DevElf.Logging/ILogMessageScope.ChangeMessage.2FDKFV78GR308BJBSTOALKPQ1.md @@ -0,0 +1,17 @@ +#### [DevElf\.Logging](README.md 'README') +### [DevElf\.Logging](DevElf.Logging.md 'DevElf\.Logging').[ILogMessageScope](ILogMessageScope.md 'DevElf\.Logging\.ILogMessageScope') + +## ILogMessageScope\.ChangeMessage\(string\) Method + +Changes the message that will be logged when this scope is disposed\. + +```csharp +void ChangeMessage(string message); +``` +#### Parameters + + + +`message` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The new message\. Cannot be [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null'), empty, or whitespace\. \ No newline at end of file diff --git a/docs/api/DevElf.Logging/ILogMessageScope.SetException.RD4VYIJ1SQ9EVWX51XVKJSNO7.md b/docs/api/DevElf.Logging/ILogMessageScope.SetException.RD4VYIJ1SQ9EVWX51XVKJSNO7.md new file mode 100644 index 0000000..d4cb6af --- /dev/null +++ b/docs/api/DevElf.Logging/ILogMessageScope.SetException.RD4VYIJ1SQ9EVWX51XVKJSNO7.md @@ -0,0 +1,23 @@ +#### [DevElf\.Logging](README.md 'README') +### [DevElf\.Logging](DevElf.Logging.md 'DevElf\.Logging').[ILogMessageScope](ILogMessageScope.md 'DevElf\.Logging\.ILogMessageScope') + +## ILogMessageScope\.SetException\(Exception, bool\) Method + +Sets an [System\.Exception](https://learn.microsoft.com/en-us/dotnet/api/system.exception 'System\.Exception') on the scope and also adds it as a scope property under the key "Exception"\. + +```csharp +void SetException(System.Exception exception, bool setAsProperty=true); +``` +#### Parameters + + + +`exception` [System\.Exception](https://learn.microsoft.com/en-us/dotnet/api/system.exception 'System\.Exception') + +The exception to associate with the log entry\. + + + +`setAsProperty` [System\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean') + +If [true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool'), also sets the exception as a property under the key "Exception"\. \ No newline at end of file diff --git a/docs/api/DevElf.Logging/ILogMessageScope.SetProperty.W33WIH8SSDTY69PIOC9JED2Q2.md b/docs/api/DevElf.Logging/ILogMessageScope.SetProperty.W33WIH8SSDTY69PIOC9JED2Q2.md new file mode 100644 index 0000000..164e460 --- /dev/null +++ b/docs/api/DevElf.Logging/ILogMessageScope.SetProperty.W33WIH8SSDTY69PIOC9JED2Q2.md @@ -0,0 +1,35 @@ +#### [DevElf\.Logging](README.md 'README') +### [DevElf\.Logging](DevElf.Logging.md 'DevElf\.Logging').[ILogMessageScope](ILogMessageScope.md 'DevElf\.Logging\.ILogMessageScope') + +## ILogMessageScope\.SetProperty\\(string, T\) Method + +Sets a property on the current scope\. +When multiple scopes are nested, child properties override parent properties with the same key\. + +```csharp +T SetProperty(string key, T value); +``` +#### Type parameters + + + +`T` + +The value type\. +#### Parameters + + + +`key` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The property key\. Cannot be [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null'), empty, or whitespace\. + + + +`value` [T](ILogMessageScope.SetProperty.W33WIH8SSDTY69PIOC9JED2Q2.md#DevElf.Logging.ILogMessageScope.SetProperty_T_(string,T).T 'DevElf\.Logging\.ILogMessageScope\.SetProperty\\(string, T\)\.T') + +The property value\. + +#### Returns +[T](ILogMessageScope.SetProperty.W33WIH8SSDTY69PIOC9JED2Q2.md#DevElf.Logging.ILogMessageScope.SetProperty_T_(string,T).T 'DevElf\.Logging\.ILogMessageScope\.SetProperty\\(string, T\)\.T') +Returns the provided [value](ILogMessageScope.SetProperty.W33WIH8SSDTY69PIOC9JED2Q2.md#DevElf.Logging.ILogMessageScope.SetProperty_T_(string,T).value 'DevElf\.Logging\.ILogMessageScope\.SetProperty\\(string, T\)\.value') to enable fluent assignment\. \ No newline at end of file diff --git a/docs/api/DevElf.Logging/ILogMessageScope.md b/docs/api/DevElf.Logging/ILogMessageScope.md new file mode 100644 index 0000000..5d91a09 --- /dev/null +++ b/docs/api/DevElf.Logging/ILogMessageScope.md @@ -0,0 +1,21 @@ +#### [DevElf\.Logging](README.md 'README') +### [DevElf\.Logging](DevElf.Logging.md 'DevElf\.Logging') + +## ILogMessageScope Interface + +Represents an ambient log message scope\. +Implementations buffer properties and emit a log entry on [System\.IDisposable\.Dispose](https://learn.microsoft.com/en-us/dotnet/api/system.idisposable.dispose 'System\.IDisposable\.Dispose')\. + +```csharp +public interface ILogMessageScope : System.IDisposable +``` + +Implements [System\.IDisposable](https://learn.microsoft.com/en-us/dotnet/api/system.idisposable 'System\.IDisposable') + +| Methods | | +| :--- | :--- | +| [ChangeEventId\(EventId\)](ILogMessageScope.ChangeEventId.2II91DHU6UBPX38ZVB3F7A973.md 'DevElf\.Logging\.ILogMessageScope\.ChangeEventId\(Microsoft\.Extensions\.Logging\.EventId\)') | Changes the [Microsoft\.Extensions\.Logging\.EventId](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.eventid 'Microsoft\.Extensions\.Logging\.EventId') that will be used when this scope emits its log entry on dispose\. | +| [ChangeLogLevel\(LogLevel\)](ILogMessageScope.ChangeLogLevel.T8V2CVT94S8T3JEG5QV4IHR23.md 'DevElf\.Logging\.ILogMessageScope\.ChangeLogLevel\(Microsoft\.Extensions\.Logging\.LogLevel\)') | Changes the log level that will be used when this scope emits its log entry on dispose\. | +| [ChangeMessage\(string\)](ILogMessageScope.ChangeMessage.2FDKFV78GR308BJBSTOALKPQ1.md 'DevElf\.Logging\.ILogMessageScope\.ChangeMessage\(string\)') | Changes the message that will be logged when this scope is disposed\. | +| [SetException\(Exception, bool\)](ILogMessageScope.SetException.RD4VYIJ1SQ9EVWX51XVKJSNO7.md 'DevElf\.Logging\.ILogMessageScope\.SetException\(System\.Exception, bool\)') | Sets an [System\.Exception](https://learn.microsoft.com/en-us/dotnet/api/system.exception 'System\.Exception') on the scope and also adds it as a scope property under the key "Exception"\. | +| [SetProperty<T>\(string, T\)](ILogMessageScope.SetProperty.W33WIH8SSDTY69PIOC9JED2Q2.md 'DevElf\.Logging\.ILogMessageScope\.SetProperty\\(string, T\)') | Sets a property on the current scope\. When multiple scopes are nested, child properties override parent properties with the same key\. | diff --git a/docs/api/DevElf.Logging/ILogMessageScopeAccessor.Current.md b/docs/api/DevElf.Logging/ILogMessageScopeAccessor.Current.md new file mode 100644 index 0000000..d594cd7 --- /dev/null +++ b/docs/api/DevElf.Logging/ILogMessageScopeAccessor.Current.md @@ -0,0 +1,14 @@ +#### [DevElf\.Logging](README.md 'README') +### [DevElf\.Logging](DevElf.Logging.md 'DevElf\.Logging').[ILogMessageScopeAccessor](ILogMessageScopeAccessor.md 'DevElf\.Logging\.ILogMessageScopeAccessor') + +## ILogMessageScopeAccessor\.Current Property + +Gets the current [ILogMessageScope](ILogMessageScope.md 'DevElf\.Logging\.ILogMessageScope'), or +[null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null') when no scope is active\. + +```csharp +DevElf.Logging.ILogMessageScope? Current { get; } +``` + +#### Property Value +[ILogMessageScope](ILogMessageScope.md 'DevElf\.Logging\.ILogMessageScope') \ No newline at end of file diff --git a/docs/api/DevElf.Logging/ILogMessageScopeAccessor.md b/docs/api/DevElf.Logging/ILogMessageScopeAccessor.md new file mode 100644 index 0000000..564f27c --- /dev/null +++ b/docs/api/DevElf.Logging/ILogMessageScopeAccessor.md @@ -0,0 +1,17 @@ +#### [DevElf\.Logging](README.md 'README') +### [DevElf\.Logging](DevElf.Logging.md 'DevElf\.Logging') + +## ILogMessageScopeAccessor Interface + +Provides access to the current [ILogMessageScope](ILogMessageScope.md 'DevElf\.Logging\.ILogMessageScope')\. + +```csharp +public interface ILogMessageScopeAccessor +``` + +Derived +↳ [LogMessageScopeAccessor](LogMessageScopeAccessor.md 'DevElf\.Logging\.LogMessageScopeAccessor') + +| Properties | | +| :--- | :--- | +| [Current](ILogMessageScopeAccessor.Current.md 'DevElf\.Logging\.ILogMessageScopeAccessor\.Current') | Gets the current [ILogMessageScope](ILogMessageScope.md 'DevElf\.Logging\.ILogMessageScope'), or [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null') when no scope is active\. | diff --git a/docs/api/DevElf.Logging/LogMessageScopeAccessor.Current.md b/docs/api/DevElf.Logging/LogMessageScopeAccessor.Current.md new file mode 100644 index 0000000..3f3b6f0 --- /dev/null +++ b/docs/api/DevElf.Logging/LogMessageScopeAccessor.Current.md @@ -0,0 +1,16 @@ +#### [DevElf\.Logging](README.md 'README') +### [DevElf\.Logging](DevElf.Logging.md 'DevElf\.Logging').[LogMessageScopeAccessor](LogMessageScopeAccessor.md 'DevElf\.Logging\.LogMessageScopeAccessor') + +## LogMessageScopeAccessor\.Current Property + +Gets the current [ILogMessageScope](ILogMessageScope.md 'DevElf\.Logging\.ILogMessageScope'), or +[null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null') when no scope is active\. + +```csharp +public DevElf.Logging.ILogMessageScope? Current { get; } +``` + +Implements [Current](ILogMessageScopeAccessor.Current.md 'DevElf\.Logging\.ILogMessageScopeAccessor\.Current') + +#### Property Value +[ILogMessageScope](ILogMessageScope.md 'DevElf\.Logging\.ILogMessageScope') \ No newline at end of file diff --git a/docs/api/DevElf.Logging/LogMessageScopeAccessor.md b/docs/api/DevElf.Logging/LogMessageScopeAccessor.md new file mode 100644 index 0000000..7b5c3d2 --- /dev/null +++ b/docs/api/DevElf.Logging/LogMessageScopeAccessor.md @@ -0,0 +1,18 @@ +#### [DevElf\.Logging](README.md 'README') +### [DevElf\.Logging](DevElf.Logging.md 'DevElf\.Logging') + +## LogMessageScopeAccessor Class + +Provides access to the current [log message scope](https://learn.microsoft.com/en-us/dotnet/api/develf.logging.logmessagescope 'DevElf\.Logging\.LogMessageScope')\. + +```csharp +public sealed class LogMessageScopeAccessor : DevElf.Logging.ILogMessageScopeAccessor +``` + +Inheritance [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') 🡒 LogMessageScopeAccessor + +Implements [ILogMessageScopeAccessor](ILogMessageScopeAccessor.md 'DevElf\.Logging\.ILogMessageScopeAccessor') + +| Properties | | +| :--- | :--- | +| [Current](LogMessageScopeAccessor.Current.md 'DevElf\.Logging\.LogMessageScopeAccessor\.Current') | Gets the current [ILogMessageScope](ILogMessageScope.md 'DevElf\.Logging\.ILogMessageScope'), or [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null') when no scope is active\. | diff --git a/docs/api/DevElf.Logging/LoggerExtensions.BeginMessageScope.md b/docs/api/DevElf.Logging/LoggerExtensions.BeginMessageScope.md new file mode 100644 index 0000000..f573725 --- /dev/null +++ b/docs/api/DevElf.Logging/LoggerExtensions.BeginMessageScope.md @@ -0,0 +1,169 @@ +#### [DevElf\.Logging](README.md 'README') +### [DevElf\.Logging](DevElf.Logging.md 'DevElf\.Logging').[LoggerExtensions](LoggerExtensions.md 'DevElf\.Logging\.LoggerExtensions') + +## LoggerExtensions\.BeginMessageScope Method + +| Overloads | | +| :--- | :--- | +| [BeginMessageScope\(this ILogger, LogLevel, EventId, string\)](LoggerExtensions.BeginMessageScope.md#DevElf.Logging.LoggerExtensions.BeginMessageScope(thisMicrosoft.Extensions.Logging.ILogger,Microsoft.Extensions.Logging.LogLevel,Microsoft.Extensions.Logging.EventId,string) 'DevElf\.Logging\.LoggerExtensions\.BeginMessageScope\(this Microsoft\.Extensions\.Logging\.ILogger, Microsoft\.Extensions\.Logging\.LogLevel, Microsoft\.Extensions\.Logging\.EventId, string\)') | Creates a new log message scope that integrates with Microsoft's logging infrastructure\. | +| [BeginMessageScope\(this ILogger, LogLevel, string\)](LoggerExtensions.BeginMessageScope.md#DevElf.Logging.LoggerExtensions.BeginMessageScope(thisMicrosoft.Extensions.Logging.ILogger,Microsoft.Extensions.Logging.LogLevel,string) 'DevElf\.Logging\.LoggerExtensions\.BeginMessageScope\(this Microsoft\.Extensions\.Logging\.ILogger, Microsoft\.Extensions\.Logging\.LogLevel, string\)') | Creates a new log message scope that integrates with Microsoft's logging infrastructure\. | +| [BeginMessageScope<TContext>\(this ILogger<TContext>, LogLevel, EventId, string\)](LoggerExtensions.BeginMessageScope.md#DevElf.Logging.LoggerExtensions.BeginMessageScope_TContext_(thisMicrosoft.Extensions.Logging.ILogger_TContext_,Microsoft.Extensions.Logging.LogLevel,Microsoft.Extensions.Logging.EventId,string) 'DevElf\.Logging\.LoggerExtensions\.BeginMessageScope\\(this Microsoft\.Extensions\.Logging\.ILogger\, Microsoft\.Extensions\.Logging\.LogLevel, Microsoft\.Extensions\.Logging\.EventId, string\)') | Creates a new log message scope that integrates with Microsoft's logging infrastructure\. | +| [BeginMessageScope<TContext>\(this ILogger<TContext>, LogLevel, string\)](LoggerExtensions.BeginMessageScope.md#DevElf.Logging.LoggerExtensions.BeginMessageScope_TContext_(thisMicrosoft.Extensions.Logging.ILogger_TContext_,Microsoft.Extensions.Logging.LogLevel,string) 'DevElf\.Logging\.LoggerExtensions\.BeginMessageScope\\(this Microsoft\.Extensions\.Logging\.ILogger\, Microsoft\.Extensions\.Logging\.LogLevel, string\)') | Creates a new log message scope that integrates with Microsoft's logging infrastructure\. | + + + +## LoggerExtensions\.BeginMessageScope\(this ILogger, LogLevel, EventId, string\) Method + +Creates a new log message scope that integrates with Microsoft's logging infrastructure\. + +```csharp +public static DevElf.Logging.ILogMessageScope BeginMessageScope(this Microsoft.Extensions.Logging.ILogger logger, Microsoft.Extensions.Logging.LogLevel logLevel, Microsoft.Extensions.Logging.EventId eventId, string message); +``` +#### Parameters + + + +`logger` [Microsoft\.Extensions\.Logging\.ILogger](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.ilogger 'Microsoft\.Extensions\.Logging\.ILogger') + +The logger instance\. + + + +`logLevel` [Microsoft\.Extensions\.Logging\.LogLevel](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.loglevel 'Microsoft\.Extensions\.Logging\.LogLevel') + +The log level for the scope\. + + + +`eventId` [Microsoft\.Extensions\.Logging\.EventId](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.eventid 'Microsoft\.Extensions\.Logging\.EventId') + +The event ID for the scope\. + + + +`message` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The log message\. + +#### Returns +[ILogMessageScope](ILogMessageScope.md 'DevElf\.Logging\.ILogMessageScope') +A new log message scope\. + + + +## LoggerExtensions\.BeginMessageScope\(this ILogger, LogLevel, string\) Method + +Creates a new log message scope that integrates with Microsoft's logging infrastructure\. + +```csharp +public static DevElf.Logging.ILogMessageScope BeginMessageScope(this Microsoft.Extensions.Logging.ILogger logger, Microsoft.Extensions.Logging.LogLevel logLevel, string message); +``` +#### Parameters + + + +`logger` [Microsoft\.Extensions\.Logging\.ILogger](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.ilogger 'Microsoft\.Extensions\.Logging\.ILogger') + +The logger instance\. + + + +`logLevel` [Microsoft\.Extensions\.Logging\.LogLevel](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.loglevel 'Microsoft\.Extensions\.Logging\.LogLevel') + +The log level for the scope\. + + + +`message` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The log message\. + +#### Returns +[ILogMessageScope](ILogMessageScope.md 'DevElf\.Logging\.ILogMessageScope') +A new log message scope\. + + + +## LoggerExtensions\.BeginMessageScope\\(this ILogger\, LogLevel, EventId, string\) Method + +Creates a new log message scope that integrates with Microsoft's logging infrastructure\. + +```csharp +public static DevElf.Logging.ILogMessageScope BeginMessageScope(this Microsoft.Extensions.Logging.ILogger logger, Microsoft.Extensions.Logging.LogLevel logLevel, Microsoft.Extensions.Logging.EventId eventId, string message); +``` +#### Type parameters + + + +`TContext` + +The logger context type\. +#### Parameters + + + +`logger` [Microsoft\.Extensions\.Logging\.ILogger<](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.ilogger-1 'Microsoft\.Extensions\.Logging\.ILogger\`1')[TContext](LoggerExtensions.md#DevElf.Logging.LoggerExtensions.BeginMessageScope_TContext_(thisMicrosoft.Extensions.Logging.ILogger_TContext_,Microsoft.Extensions.Logging.LogLevel,Microsoft.Extensions.Logging.EventId,string).TContext 'DevElf\.Logging\.LoggerExtensions\.BeginMessageScope\\(this Microsoft\.Extensions\.Logging\.ILogger\, Microsoft\.Extensions\.Logging\.LogLevel, Microsoft\.Extensions\.Logging\.EventId, string\)\.TContext')[>](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.ilogger-1 'Microsoft\.Extensions\.Logging\.ILogger\`1') + +The logger instance\. + + + +`logLevel` [Microsoft\.Extensions\.Logging\.LogLevel](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.loglevel 'Microsoft\.Extensions\.Logging\.LogLevel') + +The log level for the scope\. + + + +`eventId` [Microsoft\.Extensions\.Logging\.EventId](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.eventid 'Microsoft\.Extensions\.Logging\.EventId') + +The event ID for the scope\. + + + +`message` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The log message\. + +#### Returns +[ILogMessageScope](ILogMessageScope.md 'DevElf\.Logging\.ILogMessageScope') +A new log message scope\. + + + +## LoggerExtensions\.BeginMessageScope\\(this ILogger\, LogLevel, string\) Method + +Creates a new log message scope that integrates with Microsoft's logging infrastructure\. + +```csharp +public static DevElf.Logging.ILogMessageScope BeginMessageScope(this Microsoft.Extensions.Logging.ILogger logger, Microsoft.Extensions.Logging.LogLevel logLevel, string message); +``` +#### Type parameters + + + +`TContext` + +The logger context type\. +#### Parameters + + + +`logger` [Microsoft\.Extensions\.Logging\.ILogger<](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.ilogger-1 'Microsoft\.Extensions\.Logging\.ILogger\`1')[TContext](LoggerExtensions.md#DevElf.Logging.LoggerExtensions.BeginMessageScope_TContext_(thisMicrosoft.Extensions.Logging.ILogger_TContext_,Microsoft.Extensions.Logging.LogLevel,string).TContext 'DevElf\.Logging\.LoggerExtensions\.BeginMessageScope\\(this Microsoft\.Extensions\.Logging\.ILogger\, Microsoft\.Extensions\.Logging\.LogLevel, string\)\.TContext')[>](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.ilogger-1 'Microsoft\.Extensions\.Logging\.ILogger\`1') + +The logger instance\. + + + +`logLevel` [Microsoft\.Extensions\.Logging\.LogLevel](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.loglevel 'Microsoft\.Extensions\.Logging\.LogLevel') + +The log level for the scope\. + + + +`message` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The log message\. + +#### Returns +[ILogMessageScope](ILogMessageScope.md 'DevElf\.Logging\.ILogMessageScope') +A new log message scope\. \ No newline at end of file diff --git a/docs/api/DevElf.Logging/LoggerExtensions.md b/docs/api/DevElf.Logging/LoggerExtensions.md new file mode 100644 index 0000000..c2f6131 --- /dev/null +++ b/docs/api/DevElf.Logging/LoggerExtensions.md @@ -0,0 +1,19 @@ +#### [DevElf\.Logging](README.md 'README') +### [DevElf\.Logging](DevElf.Logging.md 'DevElf\.Logging') + +## LoggerExtensions Class + +Extension methods for [Microsoft\.Extensions\.Logging\.ILogger](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.ilogger 'Microsoft\.Extensions\.Logging\.ILogger') to integrate with [DevElf\.Logging\.LogMessageScope](https://learn.microsoft.com/en-us/dotnet/api/develf.logging.logmessagescope 'DevElf\.Logging\.LogMessageScope')\. + +```csharp +public static class LoggerExtensions +``` + +Inheritance [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') 🡒 LoggerExtensions + +| Methods | | +| :--- | :--- | +| [BeginMessageScope\(this ILogger, LogLevel, EventId, string\)](LoggerExtensions.BeginMessageScope.md#DevElf.Logging.LoggerExtensions.BeginMessageScope(thisMicrosoft.Extensions.Logging.ILogger,Microsoft.Extensions.Logging.LogLevel,Microsoft.Extensions.Logging.EventId,string) 'DevElf\.Logging\.LoggerExtensions\.BeginMessageScope\(this Microsoft\.Extensions\.Logging\.ILogger, Microsoft\.Extensions\.Logging\.LogLevel, Microsoft\.Extensions\.Logging\.EventId, string\)') | Creates a new log message scope that integrates with Microsoft's logging infrastructure\. | +| [BeginMessageScope\(this ILogger, LogLevel, string\)](LoggerExtensions.BeginMessageScope.md#DevElf.Logging.LoggerExtensions.BeginMessageScope(thisMicrosoft.Extensions.Logging.ILogger,Microsoft.Extensions.Logging.LogLevel,string) 'DevElf\.Logging\.LoggerExtensions\.BeginMessageScope\(this Microsoft\.Extensions\.Logging\.ILogger, Microsoft\.Extensions\.Logging\.LogLevel, string\)') | Creates a new log message scope that integrates with Microsoft's logging infrastructure\. | +| [BeginMessageScope<TContext>\(this ILogger<TContext>, LogLevel, EventId, string\)](LoggerExtensions.BeginMessageScope.md#DevElf.Logging.LoggerExtensions.BeginMessageScope_TContext_(thisMicrosoft.Extensions.Logging.ILogger_TContext_,Microsoft.Extensions.Logging.LogLevel,Microsoft.Extensions.Logging.EventId,string) 'DevElf\.Logging\.LoggerExtensions\.BeginMessageScope\\(this Microsoft\.Extensions\.Logging\.ILogger\, Microsoft\.Extensions\.Logging\.LogLevel, Microsoft\.Extensions\.Logging\.EventId, string\)') | Creates a new log message scope that integrates with Microsoft's logging infrastructure\. | +| [BeginMessageScope<TContext>\(this ILogger<TContext>, LogLevel, string\)](LoggerExtensions.BeginMessageScope.md#DevElf.Logging.LoggerExtensions.BeginMessageScope_TContext_(thisMicrosoft.Extensions.Logging.ILogger_TContext_,Microsoft.Extensions.Logging.LogLevel,string) 'DevElf\.Logging\.LoggerExtensions\.BeginMessageScope\\(this Microsoft\.Extensions\.Logging\.ILogger\, Microsoft\.Extensions\.Logging\.LogLevel, string\)') | Creates a new log message scope that integrates with Microsoft's logging infrastructure\. | diff --git a/docs/api/DevElf.Logging/README.md b/docs/api/DevElf.Logging/README.md new file mode 100644 index 0000000..3699fd5 --- /dev/null +++ b/docs/api/DevElf.Logging/README.md @@ -0,0 +1,7 @@ +#### [DevElf\.Logging](README.md 'README') + +## DevElf\.Logging Assembly + +| Namespaces | | +| :--- | :--- | +| [DevElf\.Logging](DevElf.Logging.md 'DevElf\.Logging') | | diff --git a/docs/api/DevElf.Logging/ServiceCollectionExtensions.AddLogMessageScopes.GDXEN2I4SIKZ4272TRDXESVJ4.md b/docs/api/DevElf.Logging/ServiceCollectionExtensions.AddLogMessageScopes.GDXEN2I4SIKZ4272TRDXESVJ4.md new file mode 100644 index 0000000..276cb16 --- /dev/null +++ b/docs/api/DevElf.Logging/ServiceCollectionExtensions.AddLogMessageScopes.GDXEN2I4SIKZ4272TRDXESVJ4.md @@ -0,0 +1,21 @@ +#### [DevElf\.Logging](README.md 'README') +### [DevElf\.Logging](DevElf.Logging.md 'DevElf\.Logging').[ServiceCollectionExtensions](ServiceCollectionExtensions.md 'DevElf\.Logging\.ServiceCollectionExtensions') + +## ServiceCollectionExtensions\.AddLogMessageScopes\(this IServiceCollection\) Method + +Adds the [ILogMessageScopeAccessor](ILogMessageScopeAccessor.md 'DevElf\.Logging\.ILogMessageScopeAccessor') service to the DI container, if not already registered\. + +```csharp +public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddLogMessageScopes(this Microsoft.Extensions.DependencyInjection.IServiceCollection services); +``` +#### Parameters + + + +`services` [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') + +The service collection\. + +#### Returns +[Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') +The same [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') for chaining\. \ No newline at end of file diff --git a/docs/api/DevElf.Logging/ServiceCollectionExtensions.md b/docs/api/DevElf.Logging/ServiceCollectionExtensions.md new file mode 100644 index 0000000..ebc3ebc --- /dev/null +++ b/docs/api/DevElf.Logging/ServiceCollectionExtensions.md @@ -0,0 +1,16 @@ +#### [DevElf\.Logging](README.md 'README') +### [DevElf\.Logging](DevElf.Logging.md 'DevElf\.Logging') + +## ServiceCollectionExtensions Class + +Extension methods for configuring log message scope services in dependency injection\. + +```csharp +public static class ServiceCollectionExtensions +``` + +Inheritance [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') 🡒 ServiceCollectionExtensions + +| Methods | | +| :--- | :--- | +| [AddLogMessageScopes\(this IServiceCollection\)](ServiceCollectionExtensions.AddLogMessageScopes.GDXEN2I4SIKZ4272TRDXESVJ4.md 'DevElf\.Logging\.ServiceCollectionExtensions\.AddLogMessageScopes\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection\)') | Adds the [ILogMessageScopeAccessor](ILogMessageScopeAccessor.md 'DevElf\.Logging\.ILogMessageScopeAccessor') service to the DI container, if not already registered\. | diff --git a/docs/api/DevElf/ComparableExtensions.ThrowIfGreaterThan.md b/docs/api/DevElf/ComparableExtensions.ThrowIfGreaterThan.md new file mode 100644 index 0000000..93174eb --- /dev/null +++ b/docs/api/DevElf/ComparableExtensions.ThrowIfGreaterThan.md @@ -0,0 +1,179 @@ +#### [DevElf](README.md 'README') +### [DevElf\.ArgumentValidation](DevElf.ArgumentValidation.md 'DevElf\.ArgumentValidation').[ComparableExtensions](ComparableExtensions.md 'DevElf\.ArgumentValidation\.ComparableExtensions') + +## ComparableExtensions\.ThrowIfGreaterThan Method + +| Overloads | | +| :--- | :--- | +| [ThrowIfGreaterThan<T>\(this Nullable<T>, Nullable<T>, string\)](ComparableExtensions.ThrowIfGreaterThan.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisSystem.Nullable_T_,System.Nullable_T_,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this System\.Nullable\, System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this System\.Nullable\, System\.Nullable\, string\)\.value') is greater than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this System\.Nullable\, System\.Nullable\, string\)\.other')\. | +| [ThrowIfGreaterThan<T>\(this Nullable<T>, T, string\)](ComparableExtensions.ThrowIfGreaterThan.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisSystem.Nullable_T_,T,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this System\.Nullable\, T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisSystem.Nullable_T_,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this System\.Nullable\, T, string\)\.value') is greater than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisSystem.Nullable_T_,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this System\.Nullable\, T, string\)\.other')\. | +| [ThrowIfGreaterThan<T>\(this T, Nullable<T>, string\)](ComparableExtensions.ThrowIfGreaterThan.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisT,System.Nullable_T_,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this T, System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisT,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this T, System\.Nullable\, string\)\.value') is greater than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisT,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this T, System\.Nullable\, string\)\.other')\. | +| [ThrowIfGreaterThan<T>\(this T, T, string\)](ComparableExtensions.ThrowIfGreaterThan.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisT,T,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this T, T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisT,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this T, T, string\)\.value') is greater than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisT,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this T, T, string\)\.other')\. | + + + +## ComparableExtensions\.ThrowIfGreaterThan\\(this Nullable\, Nullable\, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this System\.Nullable\, System\.Nullable\, string\)\.value') is greater than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this System\.Nullable\, System\.Nullable\, string\)\.other')\. + +```csharp +public static void ThrowIfGreaterThan(this System.Nullable value, System.Nullable other, string parameterName=null) + where T : struct, System.IComparable, System.ValueType, System.ValueType; +``` +#### Type parameters + + + +`T` + +The type of the arguments, which must implement [System\.IComparable<>](https://learn.microsoft.com/en-us/dotnet/api/system.icomparable-1 'System\.IComparable\`1')\. +#### Parameters + + + +`value` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this System\.Nullable\, System\.Nullable\, string\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The value to validate\. + + + +`other` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this System\.Nullable\, System\.Nullable\, string\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The value to compare against\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this System\.Nullable\, System\.Nullable\, string\)\.value') parameter \(automatically provided\)\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this System\.Nullable\, System\.Nullable\, string\)\.value') is greater than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this System\.Nullable\, System\.Nullable\, string\)\.other')\. + + + +## ComparableExtensions\.ThrowIfGreaterThan\\(this Nullable\, T, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisSystem.Nullable_T_,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this System\.Nullable\, T, string\)\.value') is greater than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisSystem.Nullable_T_,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this System\.Nullable\, T, string\)\.other')\. + +```csharp +public static void ThrowIfGreaterThan(this System.Nullable value, T other, string parameterName=null) + where T : struct, System.IComparable, System.ValueType, System.ValueType; +``` +#### Type parameters + + + +`T` + +The type of the arguments, which must implement [System\.IComparable<>](https://learn.microsoft.com/en-us/dotnet/api/system.icomparable-1 'System\.IComparable\`1')\. +#### Parameters + + + +`value` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisSystem.Nullable_T_,T,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this System\.Nullable\, T, string\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The value to validate\. + + + +`other` [T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisSystem.Nullable_T_,T,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this System\.Nullable\, T, string\)\.T') + +The value to compare against\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisSystem.Nullable_T_,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this System\.Nullable\, T, string\)\.value') parameter \(automatically provided\)\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisSystem.Nullable_T_,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this System\.Nullable\, T, string\)\.value') is greater than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisSystem.Nullable_T_,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this System\.Nullable\, T, string\)\.other')\. + + + +## ComparableExtensions\.ThrowIfGreaterThan\\(this T, Nullable\, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisT,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this T, System\.Nullable\, string\)\.value') is greater than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisT,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this T, System\.Nullable\, string\)\.other')\. + +```csharp +public static void ThrowIfGreaterThan(this T value, System.Nullable other, string parameterName=null) + where T : struct, System.IComparable, System.ValueType, System.ValueType; +``` +#### Type parameters + + + +`T` + +The type of the arguments, which must implement [System\.IComparable<>](https://learn.microsoft.com/en-us/dotnet/api/system.icomparable-1 'System\.IComparable\`1')\. +#### Parameters + + + +`value` [T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisT,System.Nullable_T_,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this T, System\.Nullable\, string\)\.T') + +The value to validate\. + + + +`other` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisT,System.Nullable_T_,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this T, System\.Nullable\, string\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The value to compare against\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisT,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this T, System\.Nullable\, string\)\.value') parameter \(automatically provided\)\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisT,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this T, System\.Nullable\, string\)\.value') is greater than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisT,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this T, System\.Nullable\, string\)\.other')\. + + + +## ComparableExtensions\.ThrowIfGreaterThan\\(this T, T, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisT,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this T, T, string\)\.value') is greater than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisT,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this T, T, string\)\.other')\. + +```csharp +public static void ThrowIfGreaterThan(this T? value, T? other, string parameterName=null) + where T : System.IComparable; +``` +#### Type parameters + + + +`T` + +The type of the arguments, which must implement [System\.IComparable<>](https://learn.microsoft.com/en-us/dotnet/api/system.icomparable-1 'System\.IComparable\`1')\. +#### Parameters + + + +`value` [T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisT,T,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this T, T, string\)\.T') + +The value to validate\. + + + +`other` [T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisT,T,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this T, T, string\)\.T') + +The value to compare against\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisT,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this T, T, string\)\.value') parameter \(automatically provided\)\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisT,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this T, T, string\)\.value') is greater than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisT,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this T, T, string\)\.other')\. \ No newline at end of file diff --git a/docs/api/DevElf/ComparableExtensions.ThrowIfGreaterThanOrEqualTo.md b/docs/api/DevElf/ComparableExtensions.ThrowIfGreaterThanOrEqualTo.md new file mode 100644 index 0000000..fb5c105 --- /dev/null +++ b/docs/api/DevElf/ComparableExtensions.ThrowIfGreaterThanOrEqualTo.md @@ -0,0 +1,179 @@ +#### [DevElf](README.md 'README') +### [DevElf\.ArgumentValidation](DevElf.ArgumentValidation.md 'DevElf\.ArgumentValidation').[ComparableExtensions](ComparableExtensions.md 'DevElf\.ArgumentValidation\.ComparableExtensions') + +## ComparableExtensions\.ThrowIfGreaterThanOrEqualTo Method + +| Overloads | | +| :--- | :--- | +| [ThrowIfGreaterThanOrEqualTo<T>\(this Nullable<T>, Nullable<T>, string\)](ComparableExtensions.ThrowIfGreaterThanOrEqualTo.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisSystem.Nullable_T_,System.Nullable_T_,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this System\.Nullable\, System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this System\.Nullable\, System\.Nullable\, string\)\.value') is greater than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this System\.Nullable\, System\.Nullable\, string\)\.other')\. | +| [ThrowIfGreaterThanOrEqualTo<T>\(this Nullable<T>, T, string\)](ComparableExtensions.ThrowIfGreaterThanOrEqualTo.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisSystem.Nullable_T_,T,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this System\.Nullable\, T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisSystem.Nullable_T_,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this System\.Nullable\, T, string\)\.value') is greater than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisSystem.Nullable_T_,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this System\.Nullable\, T, string\)\.other')\. | +| [ThrowIfGreaterThanOrEqualTo<T>\(this T, Nullable<T>, string\)](ComparableExtensions.ThrowIfGreaterThanOrEqualTo.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisT,System.Nullable_T_,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this T, System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisT,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this T, System\.Nullable\, string\)\.value') is greater than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisT,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this T, System\.Nullable\, string\)\.other')\. | +| [ThrowIfGreaterThanOrEqualTo<T>\(this T, T, string\)](ComparableExtensions.ThrowIfGreaterThanOrEqualTo.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisT,T,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this T, T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisT,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this T, T, string\)\.value') is greater than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisT,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this T, T, string\)\.other')\. | + + + +## ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this Nullable\, Nullable\, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this System\.Nullable\, System\.Nullable\, string\)\.value') is greater than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this System\.Nullable\, System\.Nullable\, string\)\.other')\. + +```csharp +public static void ThrowIfGreaterThanOrEqualTo(this System.Nullable value, System.Nullable other, string parameterName=null) + where T : struct, System.IComparable, System.ValueType, System.ValueType; +``` +#### Type parameters + + + +`T` + +The type of the arguments, which must implement [System\.IComparable<>](https://learn.microsoft.com/en-us/dotnet/api/system.icomparable-1 'System\.IComparable\`1')\. +#### Parameters + + + +`value` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this System\.Nullable\, System\.Nullable\, string\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The value to validate\. + + + +`other` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this System\.Nullable\, System\.Nullable\, string\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The value to compare against\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this System\.Nullable\, System\.Nullable\, string\)\.value') parameter \(automatically provided\)\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this System\.Nullable\, System\.Nullable\, string\)\.value') is greater than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this System\.Nullable\, System\.Nullable\, string\)\.other')\. + + + +## ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this Nullable\, T, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisSystem.Nullable_T_,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this System\.Nullable\, T, string\)\.value') is greater than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisSystem.Nullable_T_,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this System\.Nullable\, T, string\)\.other')\. + +```csharp +public static void ThrowIfGreaterThanOrEqualTo(this System.Nullable value, T other, string parameterName=null) + where T : struct, System.IComparable, System.ValueType, System.ValueType; +``` +#### Type parameters + + + +`T` + +The type of the arguments, which must implement [System\.IComparable<>](https://learn.microsoft.com/en-us/dotnet/api/system.icomparable-1 'System\.IComparable\`1')\. +#### Parameters + + + +`value` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisSystem.Nullable_T_,T,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this System\.Nullable\, T, string\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The value to validate\. + + + +`other` [T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisSystem.Nullable_T_,T,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this System\.Nullable\, T, string\)\.T') + +The value to compare against\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisSystem.Nullable_T_,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this System\.Nullable\, T, string\)\.value') parameter \(automatically provided\)\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisSystem.Nullable_T_,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this System\.Nullable\, T, string\)\.value') is greater than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisSystem.Nullable_T_,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this System\.Nullable\, T, string\)\.other')\. + + + +## ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this T, Nullable\, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisT,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this T, System\.Nullable\, string\)\.value') is greater than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisT,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this T, System\.Nullable\, string\)\.other')\. + +```csharp +public static void ThrowIfGreaterThanOrEqualTo(this T value, System.Nullable other, string parameterName=null) + where T : struct, System.IComparable, System.ValueType, System.ValueType; +``` +#### Type parameters + + + +`T` + +The type of the arguments, which must implement [System\.IComparable<>](https://learn.microsoft.com/en-us/dotnet/api/system.icomparable-1 'System\.IComparable\`1')\. +#### Parameters + + + +`value` [T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisT,System.Nullable_T_,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this T, System\.Nullable\, string\)\.T') + +The value to validate\. + + + +`other` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisT,System.Nullable_T_,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this T, System\.Nullable\, string\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The value to compare against\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisT,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this T, System\.Nullable\, string\)\.value') parameter \(automatically provided\)\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisT,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this T, System\.Nullable\, string\)\.value') is greater than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisT,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this T, System\.Nullable\, string\)\.other')\. + + + +## ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this T, T, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisT,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this T, T, string\)\.value') is greater than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisT,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this T, T, string\)\.other')\. + +```csharp +public static void ThrowIfGreaterThanOrEqualTo(this T? value, T? other, string parameterName=null) + where T : System.IComparable; +``` +#### Type parameters + + + +`T` + +The type of the arguments, which must implement [System\.IComparable<>](https://learn.microsoft.com/en-us/dotnet/api/system.icomparable-1 'System\.IComparable\`1')\. +#### Parameters + + + +`value` [T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisT,T,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this T, T, string\)\.T') + +The value to validate\. + + + +`other` [T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisT,T,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this T, T, string\)\.T') + +The value to compare against\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisT,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this T, T, string\)\.value') parameter \(automatically provided\)\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisT,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this T, T, string\)\.value') is greater than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisT,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this T, T, string\)\.other')\. \ No newline at end of file diff --git a/docs/api/DevElf/ComparableExtensions.ThrowIfLessThan.md b/docs/api/DevElf/ComparableExtensions.ThrowIfLessThan.md new file mode 100644 index 0000000..06afced --- /dev/null +++ b/docs/api/DevElf/ComparableExtensions.ThrowIfLessThan.md @@ -0,0 +1,179 @@ +#### [DevElf](README.md 'README') +### [DevElf\.ArgumentValidation](DevElf.ArgumentValidation.md 'DevElf\.ArgumentValidation').[ComparableExtensions](ComparableExtensions.md 'DevElf\.ArgumentValidation\.ComparableExtensions') + +## ComparableExtensions\.ThrowIfLessThan Method + +| Overloads | | +| :--- | :--- | +| [ThrowIfLessThan<T>\(this Nullable<T>, Nullable<T>, string\)](ComparableExtensions.ThrowIfLessThan.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisSystem.Nullable_T_,System.Nullable_T_,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this System\.Nullable\, System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this System\.Nullable\, System\.Nullable\, string\)\.value') is less than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this System\.Nullable\, System\.Nullable\, string\)\.other')\. | +| [ThrowIfLessThan<T>\(this Nullable<T>, T, string\)](ComparableExtensions.ThrowIfLessThan.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisSystem.Nullable_T_,T,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this System\.Nullable\, T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisSystem.Nullable_T_,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this System\.Nullable\, T, string\)\.value') is less than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisSystem.Nullable_T_,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this System\.Nullable\, T, string\)\.other')\. | +| [ThrowIfLessThan<T>\(this T, Nullable<T>, string\)](ComparableExtensions.ThrowIfLessThan.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisT,System.Nullable_T_,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this T, System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisT,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this T, System\.Nullable\, string\)\.value') is less than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisT,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this T, System\.Nullable\, string\)\.other')\. | +| [ThrowIfLessThan<T>\(this T, T, string\)](ComparableExtensions.ThrowIfLessThan.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisT,T,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this T, T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisT,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this T, T, string\)\.value') is less than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisT,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this T, T, string\)\.other')\. | + + + +## ComparableExtensions\.ThrowIfLessThan\\(this Nullable\, Nullable\, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this System\.Nullable\, System\.Nullable\, string\)\.value') is less than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this System\.Nullable\, System\.Nullable\, string\)\.other')\. + +```csharp +public static void ThrowIfLessThan(this System.Nullable value, System.Nullable other, string parameterName=null) + where T : struct, System.IComparable, System.ValueType, System.ValueType; +``` +#### Type parameters + + + +`T` + +The type of the arguments, which must implement [System\.IComparable<>](https://learn.microsoft.com/en-us/dotnet/api/system.icomparable-1 'System\.IComparable\`1')\. +#### Parameters + + + +`value` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this System\.Nullable\, System\.Nullable\, string\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The value to validate\. + + + +`other` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this System\.Nullable\, System\.Nullable\, string\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The value to compare against\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this System\.Nullable\, System\.Nullable\, string\)\.value') parameter \(automatically provided\)\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this System\.Nullable\, System\.Nullable\, string\)\.value') is less than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this System\.Nullable\, System\.Nullable\, string\)\.other')\. + + + +## ComparableExtensions\.ThrowIfLessThan\\(this Nullable\, T, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisSystem.Nullable_T_,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this System\.Nullable\, T, string\)\.value') is less than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisSystem.Nullable_T_,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this System\.Nullable\, T, string\)\.other')\. + +```csharp +public static void ThrowIfLessThan(this System.Nullable value, T other, string parameterName=null) + where T : struct, System.IComparable, System.ValueType, System.ValueType; +``` +#### Type parameters + + + +`T` + +The type of the arguments, which must implement [System\.IComparable<>](https://learn.microsoft.com/en-us/dotnet/api/system.icomparable-1 'System\.IComparable\`1')\. +#### Parameters + + + +`value` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisSystem.Nullable_T_,T,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this System\.Nullable\, T, string\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The value to validate\. + + + +`other` [T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisSystem.Nullable_T_,T,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this System\.Nullable\, T, string\)\.T') + +The value to compare against\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisSystem.Nullable_T_,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this System\.Nullable\, T, string\)\.value') parameter \(automatically provided\)\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisSystem.Nullable_T_,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this System\.Nullable\, T, string\)\.value') is less than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisSystem.Nullable_T_,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this System\.Nullable\, T, string\)\.other')\. + + + +## ComparableExtensions\.ThrowIfLessThan\\(this T, Nullable\, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisT,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this T, System\.Nullable\, string\)\.value') is less than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisT,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this T, System\.Nullable\, string\)\.other')\. + +```csharp +public static void ThrowIfLessThan(this T value, System.Nullable other, string parameterName=null) + where T : struct, System.IComparable, System.ValueType, System.ValueType; +``` +#### Type parameters + + + +`T` + +The type of the arguments, which must implement [System\.IComparable<>](https://learn.microsoft.com/en-us/dotnet/api/system.icomparable-1 'System\.IComparable\`1')\. +#### Parameters + + + +`value` [T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisT,System.Nullable_T_,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this T, System\.Nullable\, string\)\.T') + +The value to validate\. + + + +`other` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisT,System.Nullable_T_,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this T, System\.Nullable\, string\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The value to compare against\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisT,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this T, System\.Nullable\, string\)\.value') parameter \(automatically provided\)\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisT,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this T, System\.Nullable\, string\)\.value') is less than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisT,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this T, System\.Nullable\, string\)\.other')\. + + + +## ComparableExtensions\.ThrowIfLessThan\\(this T, T, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisT,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this T, T, string\)\.value') is less than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisT,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this T, T, string\)\.other')\. + +```csharp +public static void ThrowIfLessThan(this T? value, T? other, string parameterName=null) + where T : System.IComparable; +``` +#### Type parameters + + + +`T` + +The type of the arguments, which must implement [System\.IComparable<>](https://learn.microsoft.com/en-us/dotnet/api/system.icomparable-1 'System\.IComparable\`1')\. +#### Parameters + + + +`value` [T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisT,T,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this T, T, string\)\.T') + +The value to validate\. + + + +`other` [T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisT,T,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this T, T, string\)\.T') + +The value to compare against\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisT,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this T, T, string\)\.value') parameter \(automatically provided\)\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisT,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this T, T, string\)\.value') is less than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisT,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this T, T, string\)\.other')\. \ No newline at end of file diff --git a/docs/api/DevElf/ComparableExtensions.ThrowIfLessThanOrEqualTo.md b/docs/api/DevElf/ComparableExtensions.ThrowIfLessThanOrEqualTo.md new file mode 100644 index 0000000..cf4c30e --- /dev/null +++ b/docs/api/DevElf/ComparableExtensions.ThrowIfLessThanOrEqualTo.md @@ -0,0 +1,179 @@ +#### [DevElf](README.md 'README') +### [DevElf\.ArgumentValidation](DevElf.ArgumentValidation.md 'DevElf\.ArgumentValidation').[ComparableExtensions](ComparableExtensions.md 'DevElf\.ArgumentValidation\.ComparableExtensions') + +## ComparableExtensions\.ThrowIfLessThanOrEqualTo Method + +| Overloads | | +| :--- | :--- | +| [ThrowIfLessThanOrEqualTo<T>\(this Nullable<T>, Nullable<T>, string\)](ComparableExtensions.ThrowIfLessThanOrEqualTo.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisSystem.Nullable_T_,System.Nullable_T_,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this System\.Nullable\, System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this System\.Nullable\, System\.Nullable\, string\)\.value') is less than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this System\.Nullable\, System\.Nullable\, string\)\.other')\. | +| [ThrowIfLessThanOrEqualTo<T>\(this Nullable<T>, T, string\)](ComparableExtensions.ThrowIfLessThanOrEqualTo.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisSystem.Nullable_T_,T,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this System\.Nullable\, T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisSystem.Nullable_T_,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this System\.Nullable\, T, string\)\.value') is less than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisSystem.Nullable_T_,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this System\.Nullable\, T, string\)\.other')\. | +| [ThrowIfLessThanOrEqualTo<T>\(this T, Nullable<T>, string\)](ComparableExtensions.ThrowIfLessThanOrEqualTo.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisT,System.Nullable_T_,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this T, System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisT,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this T, System\.Nullable\, string\)\.value') is less than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisT,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this T, System\.Nullable\, string\)\.other')\. | +| [ThrowIfLessThanOrEqualTo<T>\(this T, T, string\)](ComparableExtensions.ThrowIfLessThanOrEqualTo.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisT,T,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this T, T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisT,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this T, T, string\)\.value') is less than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisT,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this T, T, string\)\.other')\. | + + + +## ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this Nullable\, Nullable\, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this System\.Nullable\, System\.Nullable\, string\)\.value') is less than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this System\.Nullable\, System\.Nullable\, string\)\.other')\. + +```csharp +public static void ThrowIfLessThanOrEqualTo(this System.Nullable value, System.Nullable other, string parameterName=null) + where T : struct, System.IComparable, System.ValueType, System.ValueType; +``` +#### Type parameters + + + +`T` + +The type of the arguments, which must implement [System\.IComparable<>](https://learn.microsoft.com/en-us/dotnet/api/system.icomparable-1 'System\.IComparable\`1')\. +#### Parameters + + + +`value` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this System\.Nullable\, System\.Nullable\, string\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The value to validate\. + + + +`other` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this System\.Nullable\, System\.Nullable\, string\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The value to compare against\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this System\.Nullable\, System\.Nullable\, string\)\.value') parameter \(automatically provided\)\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this System\.Nullable\, System\.Nullable\, string\)\.value') is less than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this System\.Nullable\, System\.Nullable\, string\)\.other')\. + + + +## ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this Nullable\, T, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisSystem.Nullable_T_,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this System\.Nullable\, T, string\)\.value') is less than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisSystem.Nullable_T_,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this System\.Nullable\, T, string\)\.other')\. + +```csharp +public static void ThrowIfLessThanOrEqualTo(this System.Nullable value, T other, string parameterName=null) + where T : struct, System.IComparable, System.ValueType, System.ValueType; +``` +#### Type parameters + + + +`T` + +The type of the arguments, which must implement [System\.IComparable<>](https://learn.microsoft.com/en-us/dotnet/api/system.icomparable-1 'System\.IComparable\`1')\. +#### Parameters + + + +`value` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisSystem.Nullable_T_,T,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this System\.Nullable\, T, string\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The value to validate\. + + + +`other` [T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisSystem.Nullable_T_,T,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this System\.Nullable\, T, string\)\.T') + +The value to compare against\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisSystem.Nullable_T_,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this System\.Nullable\, T, string\)\.value') parameter \(automatically provided\)\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisSystem.Nullable_T_,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this System\.Nullable\, T, string\)\.value') is less than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisSystem.Nullable_T_,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this System\.Nullable\, T, string\)\.other')\. + + + +## ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this T, Nullable\, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisT,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this T, System\.Nullable\, string\)\.value') is less than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisT,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this T, System\.Nullable\, string\)\.other')\. + +```csharp +public static void ThrowIfLessThanOrEqualTo(this T value, System.Nullable other, string parameterName=null) + where T : struct, System.IComparable, System.ValueType, System.ValueType; +``` +#### Type parameters + + + +`T` + +The type of the arguments, which must implement [System\.IComparable<>](https://learn.microsoft.com/en-us/dotnet/api/system.icomparable-1 'System\.IComparable\`1')\. +#### Parameters + + + +`value` [T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisT,System.Nullable_T_,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this T, System\.Nullable\, string\)\.T') + +The value to validate\. + + + +`other` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisT,System.Nullable_T_,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this T, System\.Nullable\, string\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The value to compare against\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisT,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this T, System\.Nullable\, string\)\.value') parameter \(automatically provided\)\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisT,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this T, System\.Nullable\, string\)\.value') is less than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisT,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this T, System\.Nullable\, string\)\.other')\. + + + +## ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this T, T, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisT,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this T, T, string\)\.value') is less than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisT,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this T, T, string\)\.other')\. + +```csharp +public static void ThrowIfLessThanOrEqualTo(this T? value, T? other, string parameterName=null) + where T : System.IComparable; +``` +#### Type parameters + + + +`T` + +The type of the arguments, which must implement [System\.IComparable<>](https://learn.microsoft.com/en-us/dotnet/api/system.icomparable-1 'System\.IComparable\`1')\. +#### Parameters + + + +`value` [T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisT,T,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this T, T, string\)\.T') + +The value to validate\. + + + +`other` [T](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisT,T,string).T 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this T, T, string\)\.T') + +The value to compare against\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisT,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this T, T, string\)\.value') parameter \(automatically provided\)\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisT,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this T, T, string\)\.value') is less than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisT,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this T, T, string\)\.other')\. \ No newline at end of file diff --git a/docs/api/DevElf/ComparableExtensions.md b/docs/api/DevElf/ComparableExtensions.md new file mode 100644 index 0000000..53161cb --- /dev/null +++ b/docs/api/DevElf/ComparableExtensions.md @@ -0,0 +1,31 @@ +#### [DevElf](README.md 'README') +### [DevElf\.ArgumentValidation](DevElf.ArgumentValidation.md 'DevElf\.ArgumentValidation') + +## ComparableExtensions Class + +Provides extension methods for validating comparable arguments\. + +```csharp +public static class ComparableExtensions +``` + +Inheritance [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') 🡒 ComparableExtensions + +| Methods | | +| :--- | :--- | +| [ThrowIfGreaterThan<T>\(this Nullable<T>, Nullable<T>, string\)](ComparableExtensions.ThrowIfGreaterThan.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisSystem.Nullable_T_,System.Nullable_T_,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this System\.Nullable\, System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this System\.Nullable\, System\.Nullable\, string\)\.value') is greater than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this System\.Nullable\, System\.Nullable\, string\)\.other')\. | +| [ThrowIfGreaterThan<T>\(this Nullable<T>, T, string\)](ComparableExtensions.ThrowIfGreaterThan.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisSystem.Nullable_T_,T,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this System\.Nullable\, T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisSystem.Nullable_T_,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this System\.Nullable\, T, string\)\.value') is greater than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisSystem.Nullable_T_,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this System\.Nullable\, T, string\)\.other')\. | +| [ThrowIfGreaterThan<T>\(this T, Nullable<T>, string\)](ComparableExtensions.ThrowIfGreaterThan.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisT,System.Nullable_T_,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this T, System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisT,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this T, System\.Nullable\, string\)\.value') is greater than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisT,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this T, System\.Nullable\, string\)\.other')\. | +| [ThrowIfGreaterThan<T>\(this T, T, string\)](ComparableExtensions.ThrowIfGreaterThan.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisT,T,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this T, T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisT,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this T, T, string\)\.value') is greater than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThan_T_(thisT,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThan\\(this T, T, string\)\.other')\. | +| [ThrowIfGreaterThanOrEqualTo<T>\(this Nullable<T>, Nullable<T>, string\)](ComparableExtensions.ThrowIfGreaterThanOrEqualTo.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisSystem.Nullable_T_,System.Nullable_T_,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this System\.Nullable\, System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this System\.Nullable\, System\.Nullable\, string\)\.value') is greater than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this System\.Nullable\, System\.Nullable\, string\)\.other')\. | +| [ThrowIfGreaterThanOrEqualTo<T>\(this Nullable<T>, T, string\)](ComparableExtensions.ThrowIfGreaterThanOrEqualTo.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisSystem.Nullable_T_,T,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this System\.Nullable\, T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisSystem.Nullable_T_,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this System\.Nullable\, T, string\)\.value') is greater than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisSystem.Nullable_T_,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this System\.Nullable\, T, string\)\.other')\. | +| [ThrowIfGreaterThanOrEqualTo<T>\(this T, Nullable<T>, string\)](ComparableExtensions.ThrowIfGreaterThanOrEqualTo.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisT,System.Nullable_T_,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this T, System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisT,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this T, System\.Nullable\, string\)\.value') is greater than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisT,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this T, System\.Nullable\, string\)\.other')\. | +| [ThrowIfGreaterThanOrEqualTo<T>\(this T, T, string\)](ComparableExtensions.ThrowIfGreaterThanOrEqualTo.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisT,T,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this T, T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisT,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this T, T, string\)\.value') is greater than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfGreaterThanOrEqualTo_T_(thisT,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfGreaterThanOrEqualTo\\(this T, T, string\)\.other')\. | +| [ThrowIfLessThan<T>\(this Nullable<T>, Nullable<T>, string\)](ComparableExtensions.ThrowIfLessThan.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisSystem.Nullable_T_,System.Nullable_T_,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this System\.Nullable\, System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this System\.Nullable\, System\.Nullable\, string\)\.value') is less than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this System\.Nullable\, System\.Nullable\, string\)\.other')\. | +| [ThrowIfLessThan<T>\(this Nullable<T>, T, string\)](ComparableExtensions.ThrowIfLessThan.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisSystem.Nullable_T_,T,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this System\.Nullable\, T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisSystem.Nullable_T_,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this System\.Nullable\, T, string\)\.value') is less than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisSystem.Nullable_T_,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this System\.Nullable\, T, string\)\.other')\. | +| [ThrowIfLessThan<T>\(this T, Nullable<T>, string\)](ComparableExtensions.ThrowIfLessThan.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisT,System.Nullable_T_,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this T, System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisT,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this T, System\.Nullable\, string\)\.value') is less than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisT,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this T, System\.Nullable\, string\)\.other')\. | +| [ThrowIfLessThan<T>\(this T, T, string\)](ComparableExtensions.ThrowIfLessThan.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisT,T,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this T, T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisT,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this T, T, string\)\.value') is less than [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThan_T_(thisT,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThan\\(this T, T, string\)\.other')\. | +| [ThrowIfLessThanOrEqualTo<T>\(this Nullable<T>, Nullable<T>, string\)](ComparableExtensions.ThrowIfLessThanOrEqualTo.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisSystem.Nullable_T_,System.Nullable_T_,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this System\.Nullable\, System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this System\.Nullable\, System\.Nullable\, string\)\.value') is less than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this System\.Nullable\, System\.Nullable\, string\)\.other')\. | +| [ThrowIfLessThanOrEqualTo<T>\(this Nullable<T>, T, string\)](ComparableExtensions.ThrowIfLessThanOrEqualTo.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisSystem.Nullable_T_,T,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this System\.Nullable\, T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisSystem.Nullable_T_,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this System\.Nullable\, T, string\)\.value') is less than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisSystem.Nullable_T_,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this System\.Nullable\, T, string\)\.other')\. | +| [ThrowIfLessThanOrEqualTo<T>\(this T, Nullable<T>, string\)](ComparableExtensions.ThrowIfLessThanOrEqualTo.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisT,System.Nullable_T_,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this T, System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisT,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this T, System\.Nullable\, string\)\.value') is less than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisT,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this T, System\.Nullable\, string\)\.other')\. | +| [ThrowIfLessThanOrEqualTo<T>\(this T, T, string\)](ComparableExtensions.ThrowIfLessThanOrEqualTo.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisT,T,string) 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this T, T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if [value](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisT,T,string).value 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this T, T, string\)\.value') is less than or equal to [other](ComparableExtensions.md#DevElf.ArgumentValidation.ComparableExtensions.ThrowIfLessThanOrEqualTo_T_(thisT,T,string).other 'DevElf\.ArgumentValidation\.ComparableExtensions\.ThrowIfLessThanOrEqualTo\\(this T, T, string\)\.other')\. | diff --git a/docs/api/DevElf/DateTimeOffsetExtensions.LocalTimeOfDayAsTimeOnly.3V6AA5YCYRJVWJ22EJ3V4M9HB.md b/docs/api/DevElf/DateTimeOffsetExtensions.LocalTimeOfDayAsTimeOnly.3V6AA5YCYRJVWJ22EJ3V4M9HB.md new file mode 100644 index 0000000..12ee924 --- /dev/null +++ b/docs/api/DevElf/DateTimeOffsetExtensions.LocalTimeOfDayAsTimeOnly.3V6AA5YCYRJVWJ22EJ3V4M9HB.md @@ -0,0 +1,18 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[DateTimeOffsetExtensions](DateTimeOffsetExtensions.md 'DevElf\.Extensions\.DateTimeOffsetExtensions') + +## DateTimeOffsetExtensions\.LocalTimeOfDayAsTimeOnly\(this DateTimeOffset\) Method + +Returns the local time\-of\-day component as a [System\.TimeOnly](https://learn.microsoft.com/en-us/dotnet/api/system.timeonly 'System\.TimeOnly')\. + +```csharp +public static System.TimeOnly LocalTimeOfDayAsTimeOnly(this System.DateTimeOffset dateTimeOffset); +``` +#### Parameters + + + +`dateTimeOffset` [System\.DateTimeOffset](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset 'System\.DateTimeOffset') + +#### Returns +[System\.TimeOnly](https://learn.microsoft.com/en-us/dotnet/api/system.timeonly 'System\.TimeOnly') \ No newline at end of file diff --git a/docs/api/DevElf/DateTimeOffsetExtensions.TimeOfDayAsTimeOnly.LV829LH80XT0GJ710EA0YJF1A.md b/docs/api/DevElf/DateTimeOffsetExtensions.TimeOfDayAsTimeOnly.LV829LH80XT0GJ710EA0YJF1A.md new file mode 100644 index 0000000..82e0a92 --- /dev/null +++ b/docs/api/DevElf/DateTimeOffsetExtensions.TimeOfDayAsTimeOnly.LV829LH80XT0GJ710EA0YJF1A.md @@ -0,0 +1,19 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[DateTimeOffsetExtensions](DateTimeOffsetExtensions.md 'DevElf\.Extensions\.DateTimeOffsetExtensions') + +## DateTimeOffsetExtensions\.TimeOfDayAsTimeOnly\(this DateTimeOffset\) Method + +Returns the time\-of\-day component as a [System\.TimeOnly](https://learn.microsoft.com/en-us/dotnet/api/system.timeonly 'System\.TimeOnly')\. +This represents the time portion in the offset's time zone\. + +```csharp +public static System.TimeOnly TimeOfDayAsTimeOnly(this System.DateTimeOffset dateTimeOffset); +``` +#### Parameters + + + +`dateTimeOffset` [System\.DateTimeOffset](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset 'System\.DateTimeOffset') + +#### Returns +[System\.TimeOnly](https://learn.microsoft.com/en-us/dotnet/api/system.timeonly 'System\.TimeOnly') \ No newline at end of file diff --git a/docs/api/DevElf/DateTimeOffsetExtensions.ToDateOnly.5DJTI5YJCKDCRWGSCHQA5JOD1.md b/docs/api/DevElf/DateTimeOffsetExtensions.ToDateOnly.5DJTI5YJCKDCRWGSCHQA5JOD1.md new file mode 100644 index 0000000..0a47280 --- /dev/null +++ b/docs/api/DevElf/DateTimeOffsetExtensions.ToDateOnly.5DJTI5YJCKDCRWGSCHQA5JOD1.md @@ -0,0 +1,19 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[DateTimeOffsetExtensions](DateTimeOffsetExtensions.md 'DevElf\.Extensions\.DateTimeOffsetExtensions') + +## DateTimeOffsetExtensions\.ToDateOnly\(this DateTimeOffset\) Method + +Returns the date component of the provided [System\.DateTimeOffset](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset 'System\.DateTimeOffset') as a [System\.DateOnly](https://learn.microsoft.com/en-us/dotnet/api/system.dateonly 'System\.DateOnly')\. +The date portion is taken from the [System\.DateTimeOffset\.Date](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.date 'System\.DateTimeOffset\.Date') property\. + +```csharp +public static System.DateOnly ToDateOnly(this System.DateTimeOffset dateTimeOffset); +``` +#### Parameters + + + +`dateTimeOffset` [System\.DateTimeOffset](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset 'System\.DateTimeOffset') + +#### Returns +[System\.DateOnly](https://learn.microsoft.com/en-us/dotnet/api/system.dateonly 'System\.DateOnly') \ No newline at end of file diff --git a/docs/api/DevElf/DateTimeOffsetExtensions.ToLocalDateOnly.9MOVTIQPSF8VLKP71YIJ9VH0F.md b/docs/api/DevElf/DateTimeOffsetExtensions.ToLocalDateOnly.9MOVTIQPSF8VLKP71YIJ9VH0F.md new file mode 100644 index 0000000..bbaad2f --- /dev/null +++ b/docs/api/DevElf/DateTimeOffsetExtensions.ToLocalDateOnly.9MOVTIQPSF8VLKP71YIJ9VH0F.md @@ -0,0 +1,18 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[DateTimeOffsetExtensions](DateTimeOffsetExtensions.md 'DevElf\.Extensions\.DateTimeOffsetExtensions') + +## DateTimeOffsetExtensions\.ToLocalDateOnly\(this DateTimeOffset\) Method + +Returns the local date component of the provided [System\.DateTimeOffset](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset 'System\.DateTimeOffset') as a [System\.DateOnly](https://learn.microsoft.com/en-us/dotnet/api/system.dateonly 'System\.DateOnly')\. + +```csharp +public static System.DateOnly ToLocalDateOnly(this System.DateTimeOffset dateTimeOffset); +``` +#### Parameters + + + +`dateTimeOffset` [System\.DateTimeOffset](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset 'System\.DateTimeOffset') + +#### Returns +[System\.DateOnly](https://learn.microsoft.com/en-us/dotnet/api/system.dateonly 'System\.DateOnly') \ No newline at end of file diff --git a/docs/api/DevElf/DateTimeOffsetExtensions.ToUtcDateOnly.8GHFUS2T4LHILJG3WKPW3KX85.md b/docs/api/DevElf/DateTimeOffsetExtensions.ToUtcDateOnly.8GHFUS2T4LHILJG3WKPW3KX85.md new file mode 100644 index 0000000..37ec654 --- /dev/null +++ b/docs/api/DevElf/DateTimeOffsetExtensions.ToUtcDateOnly.8GHFUS2T4LHILJG3WKPW3KX85.md @@ -0,0 +1,18 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[DateTimeOffsetExtensions](DateTimeOffsetExtensions.md 'DevElf\.Extensions\.DateTimeOffsetExtensions') + +## DateTimeOffsetExtensions\.ToUtcDateOnly\(this DateTimeOffset\) Method + +Returns the UTC date component of the provided [System\.DateTimeOffset](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset 'System\.DateTimeOffset') as a [System\.DateOnly](https://learn.microsoft.com/en-us/dotnet/api/system.dateonly 'System\.DateOnly')\. + +```csharp +public static System.DateOnly ToUtcDateOnly(this System.DateTimeOffset dateTimeOffset); +``` +#### Parameters + + + +`dateTimeOffset` [System\.DateTimeOffset](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset 'System\.DateTimeOffset') + +#### Returns +[System\.DateOnly](https://learn.microsoft.com/en-us/dotnet/api/system.dateonly 'System\.DateOnly') \ No newline at end of file diff --git a/docs/api/DevElf/DateTimeOffsetExtensions.md b/docs/api/DevElf/DateTimeOffsetExtensions.md new file mode 100644 index 0000000..028e1d6 --- /dev/null +++ b/docs/api/DevElf/DateTimeOffsetExtensions.md @@ -0,0 +1,20 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions') + +## DateTimeOffsetExtensions Class + +Extension helpers for [System\.DateTimeOffset](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset 'System\.DateTimeOffset') conversions to [System\.DateOnly](https://learn.microsoft.com/en-us/dotnet/api/system.dateonly 'System\.DateOnly') and [System\.TimeOnly](https://learn.microsoft.com/en-us/dotnet/api/system.timeonly 'System\.TimeOnly')\. + +```csharp +public static class DateTimeOffsetExtensions +``` + +Inheritance [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') 🡒 DateTimeOffsetExtensions + +| Methods | | +| :--- | :--- | +| [LocalTimeOfDayAsTimeOnly\(this DateTimeOffset\)](DateTimeOffsetExtensions.LocalTimeOfDayAsTimeOnly.3V6AA5YCYRJVWJ22EJ3V4M9HB.md 'DevElf\.Extensions\.DateTimeOffsetExtensions\.LocalTimeOfDayAsTimeOnly\(this System\.DateTimeOffset\)') | Returns the local time\-of\-day component as a [System\.TimeOnly](https://learn.microsoft.com/en-us/dotnet/api/system.timeonly 'System\.TimeOnly')\. | +| [TimeOfDayAsTimeOnly\(this DateTimeOffset\)](DateTimeOffsetExtensions.TimeOfDayAsTimeOnly.LV829LH80XT0GJ710EA0YJF1A.md 'DevElf\.Extensions\.DateTimeOffsetExtensions\.TimeOfDayAsTimeOnly\(this System\.DateTimeOffset\)') | Returns the time\-of\-day component as a [System\.TimeOnly](https://learn.microsoft.com/en-us/dotnet/api/system.timeonly 'System\.TimeOnly')\. This represents the time portion in the offset's time zone\. | +| [ToDateOnly\(this DateTimeOffset\)](DateTimeOffsetExtensions.ToDateOnly.5DJTI5YJCKDCRWGSCHQA5JOD1.md 'DevElf\.Extensions\.DateTimeOffsetExtensions\.ToDateOnly\(this System\.DateTimeOffset\)') | Returns the date component of the provided [System\.DateTimeOffset](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset 'System\.DateTimeOffset') as a [System\.DateOnly](https://learn.microsoft.com/en-us/dotnet/api/system.dateonly 'System\.DateOnly')\. The date portion is taken from the [System\.DateTimeOffset\.Date](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.date 'System\.DateTimeOffset\.Date') property\. | +| [ToLocalDateOnly\(this DateTimeOffset\)](DateTimeOffsetExtensions.ToLocalDateOnly.9MOVTIQPSF8VLKP71YIJ9VH0F.md 'DevElf\.Extensions\.DateTimeOffsetExtensions\.ToLocalDateOnly\(this System\.DateTimeOffset\)') | Returns the local date component of the provided [System\.DateTimeOffset](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset 'System\.DateTimeOffset') as a [System\.DateOnly](https://learn.microsoft.com/en-us/dotnet/api/system.dateonly 'System\.DateOnly')\. | +| [ToUtcDateOnly\(this DateTimeOffset\)](DateTimeOffsetExtensions.ToUtcDateOnly.8GHFUS2T4LHILJG3WKPW3KX85.md 'DevElf\.Extensions\.DateTimeOffsetExtensions\.ToUtcDateOnly\(this System\.DateTimeOffset\)') | Returns the UTC date component of the provided [System\.DateTimeOffset](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset 'System\.DateTimeOffset') as a [System\.DateOnly](https://learn.microsoft.com/en-us/dotnet/api/system.dateonly 'System\.DateOnly')\. | diff --git a/docs/api/DevElf/DevElf.ArgumentValidation.md b/docs/api/DevElf/DevElf.ArgumentValidation.md new file mode 100644 index 0000000..c1d35ef --- /dev/null +++ b/docs/api/DevElf/DevElf.ArgumentValidation.md @@ -0,0 +1,13 @@ +#### [DevElf](README.md 'README') + +## DevElf\.ArgumentValidation Namespace + +| Classes | | +| :--- | :--- | +| [ComparableExtensions](ComparableExtensions.md 'DevElf\.ArgumentValidation\.ComparableExtensions') | Provides extension methods for validating comparable arguments\. | +| [EnumerableExtensions](EnumerableExtensions.md 'DevElf\.ArgumentValidation\.EnumerableExtensions') | Provides argument validation extension methods for [System\.Collections\.Generic\.IEnumerable<>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 'System\.Collections\.Generic\.IEnumerable\`1') collections\. | +| [EnumExtensions](EnumExtensions.md 'DevElf\.ArgumentValidation\.EnumExtensions') | Provides helpers for validating enum arguments\. | +| [EquatableExtensions](EquatableExtensions.md 'DevElf\.ArgumentValidation\.EquatableExtensions') | Provides extension methods for [System\.IEquatable<>](https://learn.microsoft.com/en-us/dotnet/api/system.iequatable-1 'System\.IEquatable\`1') types\. | +| [GenericExtensions](GenericExtensions.md 'DevElf\.ArgumentValidation\.GenericExtensions') | Provides argument validation helpers for reference types and nullable value types\. | +| [NumberBaseExtensions](NumberBaseExtensions.md 'DevElf\.ArgumentValidation\.NumberBaseExtensions') | Provides extension methods for validating arguments of type [System\.Numerics\.INumberBase<>](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.inumberbase-1 'System\.Numerics\.INumberBase\`1')\. | +| [StringExtensions](StringExtensions.md 'DevElf\.ArgumentValidation\.StringExtensions') | Provides extension helpers for validating [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') arguments\. | diff --git a/docs/api/DevElf/DevElf.Extensions.md b/docs/api/DevElf/DevElf.Extensions.md new file mode 100644 index 0000000..528a2eb --- /dev/null +++ b/docs/api/DevElf/DevElf.Extensions.md @@ -0,0 +1,14 @@ +#### [DevElf](README.md 'README') + +## DevElf\.Extensions Namespace + +| Classes | | +| :--- | :--- | +| [DateTimeOffsetExtensions](DateTimeOffsetExtensions.md 'DevElf\.Extensions\.DateTimeOffsetExtensions') | Extension helpers for [System\.DateTimeOffset](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset 'System\.DateTimeOffset') conversions to [System\.DateOnly](https://learn.microsoft.com/en-us/dotnet/api/system.dateonly 'System\.DateOnly') and [System\.TimeOnly](https://learn.microsoft.com/en-us/dotnet/api/system.timeonly 'System\.TimeOnly')\. | +| [EnumerableExtensions](EnumerableExtensions.md 'DevElf\.Extensions\.EnumerableExtensions') | Provides extension methods for [System\.Collections\.Generic\.IEnumerable<>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 'System\.Collections\.Generic\.IEnumerable\`1') collections\. | +| [EnumExtensions](EnumExtensions.md 'DevElf\.Extensions\.EnumExtensions') | Provides extension methods for enum types to check if values are defined\. | +| [LambdaExtensions](LambdaExtensions.md 'DevElf\.Extensions\.LambdaExtensions') | Provides extension methods for delegates\. | +| [StringExtensions](StringExtensions.md 'DevElf\.Extensions\.StringExtensions') | Convenience extension methods for nullable [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') instances\. These helpers make common null/empty/whitespace checks read more clearly at call sites\. | +| [TimeProviderExtensions](TimeProviderExtensions.md 'DevElf\.Extensions\.TimeProviderExtensions') | Extension methods for [System\.TimeProvider](https://learn.microsoft.com/en-us/dotnet/api/system.timeprovider 'System\.TimeProvider') to provide convenient conversions and helpers\. | +| [TypeExtensions](TypeExtensions.md 'DevElf\.Extensions\.TypeExtensions') | Provides extension methods for [System\.Type](https://learn.microsoft.com/en-us/dotnet/api/system.type 'System\.Type') to simplify type name formatting and type analysis operations\. | +| [TypeExtensions\.<G>$6B6159A298CA62A8C577E514BE40E3DD](TypeExtensions._G_$6B6159A298CA62A8C577E514BE40E3DD.md 'DevElf\.Extensions\.TypeExtensions\.\$6B6159A298CA62A8C577E514BE40E3DD') | | diff --git a/docs/api/DevElf/DevElf.md b/docs/api/DevElf/DevElf.md new file mode 100644 index 0000000..883914a --- /dev/null +++ b/docs/api/DevElf/DevElf.md @@ -0,0 +1,7 @@ +#### [DevElf](README.md 'README') + +## DevElf Namespace + +| Classes | | +| :--- | :--- | +| [FrozenTimeProvider](FrozenTimeProvider.md 'DevElf\.FrozenTimeProvider') | A [System\.TimeProvider](https://learn.microsoft.com/en-us/dotnet/api/system.timeprovider 'System\.TimeProvider') that always returns a fixed point in time\. Useful for tests and deterministic time\-dependent logic\. | diff --git a/docs/api/DevElf/EnumExtensions.IsDefined.0N6AKTCYCMQW0BJOS1GLOX8Q9.md b/docs/api/DevElf/EnumExtensions.IsDefined.0N6AKTCYCMQW0BJOS1GLOX8Q9.md new file mode 100644 index 0000000..545f1f8 --- /dev/null +++ b/docs/api/DevElf/EnumExtensions.IsDefined.0N6AKTCYCMQW0BJOS1GLOX8Q9.md @@ -0,0 +1,29 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[EnumExtensions](EnumExtensions.md 'DevElf\.Extensions\.EnumExtensions') + +## EnumExtensions\.IsDefined\\(this TEnum\) Method + +Determines whether the specified enum value is defined in its enum type\. + +```csharp +public static bool IsDefined(this TEnum value) + where TEnum : struct, System.Enum, System.ValueType, System.ValueType; +``` +#### Type parameters + + + +`TEnum` + +The enum type\. +#### Parameters + + + +`value` [TEnum](EnumExtensions.IsDefined.0N6AKTCYCMQW0BJOS1GLOX8Q9.md#DevElf.Extensions.EnumExtensions.IsDefined_TEnum_(thisTEnum).TEnum 'DevElf\.Extensions\.EnumExtensions\.IsDefined\\(this TEnum\)\.TEnum') + +The enum value to check\. + +#### Returns +[System\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean') +[true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool') if the enum value is defined; otherwise, [false](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool')\. \ No newline at end of file diff --git a/docs/api/DevElf/EnumExtensions.IsNotDefined.RY2DLHY3SWCK2LPWGAEY4HEMA.md b/docs/api/DevElf/EnumExtensions.IsNotDefined.RY2DLHY3SWCK2LPWGAEY4HEMA.md new file mode 100644 index 0000000..e9391ce --- /dev/null +++ b/docs/api/DevElf/EnumExtensions.IsNotDefined.RY2DLHY3SWCK2LPWGAEY4HEMA.md @@ -0,0 +1,29 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[EnumExtensions](EnumExtensions.md 'DevElf\.Extensions\.EnumExtensions') + +## EnumExtensions\.IsNotDefined\\(this TEnum\) Method + +Determines whether the specified enum value is not defined in its enum type\. + +```csharp +public static bool IsNotDefined(this TEnum value) + where TEnum : struct, System.Enum, System.ValueType, System.ValueType; +``` +#### Type parameters + + + +`TEnum` + +The enum type\. +#### Parameters + + + +`value` [TEnum](EnumExtensions.IsNotDefined.RY2DLHY3SWCK2LPWGAEY4HEMA.md#DevElf.Extensions.EnumExtensions.IsNotDefined_TEnum_(thisTEnum).TEnum 'DevElf\.Extensions\.EnumExtensions\.IsNotDefined\\(this TEnum\)\.TEnum') + +The enum value to check\. + +#### Returns +[System\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean') +[true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool') if the enum value is not defined; otherwise, [false](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool')\. \ No newline at end of file diff --git a/docs/api/DevElf/EnumExtensions.ThrowIfNotDefined.OUB1Y4FPQFP2H9KPNZ3994UB8.md b/docs/api/DevElf/EnumExtensions.ThrowIfNotDefined.OUB1Y4FPQFP2H9KPNZ3994UB8.md new file mode 100644 index 0000000..295293b --- /dev/null +++ b/docs/api/DevElf/EnumExtensions.ThrowIfNotDefined.OUB1Y4FPQFP2H9KPNZ3994UB8.md @@ -0,0 +1,38 @@ +#### [DevElf](README.md 'README') +### [DevElf\.ArgumentValidation](DevElf.ArgumentValidation.md 'DevElf\.ArgumentValidation').[EnumExtensions](EnumExtensions.md 'DevElf\.ArgumentValidation\.EnumExtensions') + +## EnumExtensions\.ThrowIfNotDefined\\(this TEnum, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') when the provided enum value is not defined +for the enum type [TEnum](EnumExtensions.ThrowIfNotDefined.OUB1Y4FPQFP2H9KPNZ3994UB8.md#DevElf.ArgumentValidation.EnumExtensions.ThrowIfNotDefined_TEnum_(thisTEnum,string).TEnum 'DevElf\.ArgumentValidation\.EnumExtensions\.ThrowIfNotDefined\\(this TEnum, string\)\.TEnum')\. + +```csharp +public static void ThrowIfNotDefined(this TEnum argument, string parameterName=null) + where TEnum : struct, System.Enum, System.ValueType, System.ValueType; +``` +#### Type parameters + + + +`TEnum` + +The enum type to validate\. +#### Parameters + + + +`argument` [TEnum](EnumExtensions.ThrowIfNotDefined.OUB1Y4FPQFP2H9KPNZ3994UB8.md#DevElf.ArgumentValidation.EnumExtensions.ThrowIfNotDefined_TEnum_(thisTEnum,string).TEnum 'DevElf\.ArgumentValidation\.EnumExtensions\.ThrowIfNotDefined\\(this TEnum, string\)\.TEnum') + +The enum value to validate\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the parameter\. This is supplied automatically by the compiler when the method is +used as an extension method because of the [System\.Runtime\.CompilerServices\.CallerArgumentExpressionAttribute](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.callerargumentexpressionattribute 'System\.Runtime\.CompilerServices\.CallerArgumentExpressionAttribute') on this parameter\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when [argument](EnumExtensions.ThrowIfNotDefined.OUB1Y4FPQFP2H9KPNZ3994UB8.md#DevElf.ArgumentValidation.EnumExtensions.ThrowIfNotDefined_TEnum_(thisTEnum,string).argument 'DevElf\.ArgumentValidation\.EnumExtensions\.ThrowIfNotDefined\\(this TEnum, string\)\.argument') is not a defined value\. \ No newline at end of file diff --git a/docs/api/DevElf/EnumExtensions.md b/docs/api/DevElf/EnumExtensions.md new file mode 100644 index 0000000..da56aad --- /dev/null +++ b/docs/api/DevElf/EnumExtensions.md @@ -0,0 +1,16 @@ +#### [DevElf](README.md 'README') +### [DevElf\.ArgumentValidation](DevElf.ArgumentValidation.md 'DevElf\.ArgumentValidation') + +## EnumExtensions Class + +Provides helpers for validating enum arguments\. + +```csharp +public static class EnumExtensions +``` + +Inheritance [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') 🡒 EnumExtensions + +| Methods | | +| :--- | :--- | +| [ThrowIfNotDefined<TEnum>\(this TEnum, string\)](EnumExtensions.ThrowIfNotDefined.OUB1Y4FPQFP2H9KPNZ3994UB8.md 'DevElf\.ArgumentValidation\.EnumExtensions\.ThrowIfNotDefined\\(this TEnum, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') when the provided enum value is not defined for the enum type [TEnum](EnumExtensions.ThrowIfNotDefined.OUB1Y4FPQFP2H9KPNZ3994UB8.md#DevElf.ArgumentValidation.EnumExtensions.ThrowIfNotDefined_TEnum_(thisTEnum,string).TEnum 'DevElf\.ArgumentValidation\.EnumExtensions\.ThrowIfNotDefined\\(this TEnum, string\)\.TEnum')\. | diff --git a/docs/api/DevElf/EnumerableExtensions.IsEmpty.G3EUDQ6V6NURF5GQ19WB5WJ1B.md b/docs/api/DevElf/EnumerableExtensions.IsEmpty.G3EUDQ6V6NURF5GQ19WB5WJ1B.md new file mode 100644 index 0000000..d958683 --- /dev/null +++ b/docs/api/DevElf/EnumerableExtensions.IsEmpty.G3EUDQ6V6NURF5GQ19WB5WJ1B.md @@ -0,0 +1,34 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[EnumerableExtensions](EnumerableExtensions.md 'DevElf\.Extensions\.EnumerableExtensions') + +## EnumerableExtensions\.IsEmpty\\(this IEnumerable\\) Method + +Determines whether the specified enumerable is empty\. + +```csharp +public static bool IsEmpty(this System.Collections.Generic.IEnumerable source); +``` +#### Type parameters + + + +`T` + +The type of elements in the enumerable\. +#### Parameters + + + +`source` [System\.Collections\.Generic\.IEnumerable<](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 'System\.Collections\.Generic\.IEnumerable\`1')[T](EnumerableExtensions.IsEmpty.G3EUDQ6V6NURF5GQ19WB5WJ1B.md#DevElf.Extensions.EnumerableExtensions.IsEmpty_T_(thisSystem.Collections.Generic.IEnumerable_T_).T 'DevElf\.Extensions\.EnumerableExtensions\.IsEmpty\\(this System\.Collections\.Generic\.IEnumerable\\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 'System\.Collections\.Generic\.IEnumerable\`1') + +The enumerable to check\. + +#### Returns +[System\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean') +[true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool') if the enumerable is empty; otherwise, + [false](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool')\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +[source](EnumerableExtensions.IsEmpty.G3EUDQ6V6NURF5GQ19WB5WJ1B.md#DevElf.Extensions.EnumerableExtensions.IsEmpty_T_(thisSystem.Collections.Generic.IEnumerable_T_).source 'DevElf\.Extensions\.EnumerableExtensions\.IsEmpty\\(this System\.Collections\.Generic\.IEnumerable\\)\.source') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. \ No newline at end of file diff --git a/docs/api/DevElf/EnumerableExtensions.IsNotEmpty.YHWIUF0FBFXTBPAJA3GTXT912.md b/docs/api/DevElf/EnumerableExtensions.IsNotEmpty.YHWIUF0FBFXTBPAJA3GTXT912.md new file mode 100644 index 0000000..b733047 --- /dev/null +++ b/docs/api/DevElf/EnumerableExtensions.IsNotEmpty.YHWIUF0FBFXTBPAJA3GTXT912.md @@ -0,0 +1,34 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[EnumerableExtensions](EnumerableExtensions.md 'DevElf\.Extensions\.EnumerableExtensions') + +## EnumerableExtensions\.IsNotEmpty\\(this IEnumerable\\) Method + +Determines whether the specified enumerable is not empty\. + +```csharp +public static bool IsNotEmpty(this System.Collections.Generic.IEnumerable source); +``` +#### Type parameters + + + +`T` + +The type of elements in the enumerable\. +#### Parameters + + + +`source` [System\.Collections\.Generic\.IEnumerable<](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 'System\.Collections\.Generic\.IEnumerable\`1')[T](EnumerableExtensions.IsNotEmpty.YHWIUF0FBFXTBPAJA3GTXT912.md#DevElf.Extensions.EnumerableExtensions.IsNotEmpty_T_(thisSystem.Collections.Generic.IEnumerable_T_).T 'DevElf\.Extensions\.EnumerableExtensions\.IsNotEmpty\\(this System\.Collections\.Generic\.IEnumerable\\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 'System\.Collections\.Generic\.IEnumerable\`1') + +The enumerable to check\. + +#### Returns +[System\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean') +[true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool') if the enumerable is not empty; otherwise, + [false](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool')\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +[source](EnumerableExtensions.IsNotEmpty.YHWIUF0FBFXTBPAJA3GTXT912.md#DevElf.Extensions.EnumerableExtensions.IsNotEmpty_T_(thisSystem.Collections.Generic.IEnumerable_T_).source 'DevElf\.Extensions\.EnumerableExtensions\.IsNotEmpty\\(this System\.Collections\.Generic\.IEnumerable\\)\.source') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. \ No newline at end of file diff --git a/docs/api/DevElf/EnumerableExtensions.IsNotNullOrEmpty.IC9LTCW13TGHLKM4O0YNM0V96.md b/docs/api/DevElf/EnumerableExtensions.IsNotNullOrEmpty.IC9LTCW13TGHLKM4O0YNM0V96.md new file mode 100644 index 0000000..05a863a --- /dev/null +++ b/docs/api/DevElf/EnumerableExtensions.IsNotNullOrEmpty.IC9LTCW13TGHLKM4O0YNM0V96.md @@ -0,0 +1,30 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[EnumerableExtensions](EnumerableExtensions.md 'DevElf\.Extensions\.EnumerableExtensions') + +## EnumerableExtensions\.IsNotNullOrEmpty\\(this IEnumerable\\) Method + +Determines whether the specified enumerable is not [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null') +and not empty\. + +```csharp +public static bool IsNotNullOrEmpty(this System.Collections.Generic.IEnumerable? source); +``` +#### Type parameters + + + +`T` + +The type of elements in the enumerable\. +#### Parameters + + + +`source` [System\.Collections\.Generic\.IEnumerable<](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 'System\.Collections\.Generic\.IEnumerable\`1')[T](EnumerableExtensions.IsNotNullOrEmpty.IC9LTCW13TGHLKM4O0YNM0V96.md#DevElf.Extensions.EnumerableExtensions.IsNotNullOrEmpty_T_(thisSystem.Collections.Generic.IEnumerable_T_).T 'DevElf\.Extensions\.EnumerableExtensions\.IsNotNullOrEmpty\\(this System\.Collections\.Generic\.IEnumerable\\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 'System\.Collections\.Generic\.IEnumerable\`1') + +The enumerable to check\. + +#### Returns +[System\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean') +[true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool') if the enumerable is not [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null') + and not empty; otherwise, [false](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool')\. \ No newline at end of file diff --git a/docs/api/DevElf/EnumerableExtensions.IsNullOrEmpty.L8EM3HR11BCX0GSI8EE8Q05H6.md b/docs/api/DevElf/EnumerableExtensions.IsNullOrEmpty.L8EM3HR11BCX0GSI8EE8Q05H6.md new file mode 100644 index 0000000..8d73001 --- /dev/null +++ b/docs/api/DevElf/EnumerableExtensions.IsNullOrEmpty.L8EM3HR11BCX0GSI8EE8Q05H6.md @@ -0,0 +1,30 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[EnumerableExtensions](EnumerableExtensions.md 'DevElf\.Extensions\.EnumerableExtensions') + +## EnumerableExtensions\.IsNullOrEmpty\\(this IEnumerable\\) Method + +Determines whether the specified enumerable is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null') or +empty\. + +```csharp +public static bool IsNullOrEmpty(this System.Collections.Generic.IEnumerable? source); +``` +#### Type parameters + + + +`T` + +The type of elements in the enumerable\. +#### Parameters + + + +`source` [System\.Collections\.Generic\.IEnumerable<](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 'System\.Collections\.Generic\.IEnumerable\`1')[T](EnumerableExtensions.IsNullOrEmpty.L8EM3HR11BCX0GSI8EE8Q05H6.md#DevElf.Extensions.EnumerableExtensions.IsNullOrEmpty_T_(thisSystem.Collections.Generic.IEnumerable_T_).T 'DevElf\.Extensions\.EnumerableExtensions\.IsNullOrEmpty\\(this System\.Collections\.Generic\.IEnumerable\\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 'System\.Collections\.Generic\.IEnumerable\`1') + +The enumerable to check\. + +#### Returns +[System\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean') +[true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool') if the enumerable is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null') or + empty; otherwise, [false](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool')\. \ No newline at end of file diff --git a/docs/api/DevElf/EnumerableExtensions.ThrowIfNullOrEmpty.HOGY2PMFWW387IVPL7H586RR.md b/docs/api/DevElf/EnumerableExtensions.ThrowIfNullOrEmpty.HOGY2PMFWW387IVPL7H586RR.md new file mode 100644 index 0000000..9a16466 --- /dev/null +++ b/docs/api/DevElf/EnumerableExtensions.ThrowIfNullOrEmpty.HOGY2PMFWW387IVPL7H586RR.md @@ -0,0 +1,41 @@ +#### [DevElf](README.md 'README') +### [DevElf\.ArgumentValidation](DevElf.ArgumentValidation.md 'DevElf\.ArgumentValidation').[EnumerableExtensions](EnumerableExtensions.md 'DevElf\.ArgumentValidation\.EnumerableExtensions') + +## EnumerableExtensions\.ThrowIfNullOrEmpty\\(this IEnumerable\, string\) Method + +Throws an [System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') if the enumerable is +[null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null') or an [System\.ArgumentException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentexception 'System\.ArgumentException') if the +enumerable is empty\. + +```csharp +public static void ThrowIfNullOrEmpty(this System.Collections.Generic.IEnumerable source, string parameterName=null); +``` +#### Type parameters + + + +`T` + +The type of elements in the enumerable\. +#### Parameters + + + +`source` [System\.Collections\.Generic\.IEnumerable<](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 'System\.Collections\.Generic\.IEnumerable\`1')[T](EnumerableExtensions.ThrowIfNullOrEmpty.HOGY2PMFWW387IVPL7H586RR.md#DevElf.ArgumentValidation.EnumerableExtensions.ThrowIfNullOrEmpty_T_(thisSystem.Collections.Generic.IEnumerable_T_,string).T 'DevElf\.ArgumentValidation\.EnumerableExtensions\.ThrowIfNullOrEmpty\\(this System\.Collections\.Generic\.IEnumerable\, string\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 'System\.Collections\.Generic\.IEnumerable\`1') + +The enumerable to validate\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the parameter being validated\. This is automatically +captured from the calling code\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +[source](EnumerableExtensions.ThrowIfNullOrEmpty.HOGY2PMFWW387IVPL7H586RR.md#DevElf.ArgumentValidation.EnumerableExtensions.ThrowIfNullOrEmpty_T_(thisSystem.Collections.Generic.IEnumerable_T_,string).source 'DevElf\.ArgumentValidation\.EnumerableExtensions\.ThrowIfNullOrEmpty\\(this System\.Collections\.Generic\.IEnumerable\, string\)\.source') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + +[System\.ArgumentException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentexception 'System\.ArgumentException') +[source](EnumerableExtensions.ThrowIfNullOrEmpty.HOGY2PMFWW387IVPL7H586RR.md#DevElf.ArgumentValidation.EnumerableExtensions.ThrowIfNullOrEmpty_T_(thisSystem.Collections.Generic.IEnumerable_T_,string).source 'DevElf\.ArgumentValidation\.EnumerableExtensions\.ThrowIfNullOrEmpty\\(this System\.Collections\.Generic\.IEnumerable\, string\)\.source') is empty\. \ No newline at end of file diff --git a/docs/api/DevElf/EnumerableExtensions.md b/docs/api/DevElf/EnumerableExtensions.md new file mode 100644 index 0000000..5459cfc --- /dev/null +++ b/docs/api/DevElf/EnumerableExtensions.md @@ -0,0 +1,17 @@ +#### [DevElf](README.md 'README') +### [DevElf\.ArgumentValidation](DevElf.ArgumentValidation.md 'DevElf\.ArgumentValidation') + +## EnumerableExtensions Class + +Provides argument validation extension methods for [System\.Collections\.Generic\.IEnumerable<>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 'System\.Collections\.Generic\.IEnumerable\`1') +collections\. + +```csharp +public static class EnumerableExtensions +``` + +Inheritance [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') 🡒 EnumerableExtensions + +| Methods | | +| :--- | :--- | +| [ThrowIfNullOrEmpty<T>\(this IEnumerable<T>, string\)](EnumerableExtensions.ThrowIfNullOrEmpty.HOGY2PMFWW387IVPL7H586RR.md 'DevElf\.ArgumentValidation\.EnumerableExtensions\.ThrowIfNullOrEmpty\\(this System\.Collections\.Generic\.IEnumerable\, string\)') | Throws an [System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') if the enumerable is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null') or an [System\.ArgumentException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentexception 'System\.ArgumentException') if the enumerable is empty\. | diff --git a/docs/api/DevElf/EquatableExtensions.ThrowIfEqual.md b/docs/api/DevElf/EquatableExtensions.ThrowIfEqual.md new file mode 100644 index 0000000..6f97854 --- /dev/null +++ b/docs/api/DevElf/EquatableExtensions.ThrowIfEqual.md @@ -0,0 +1,183 @@ +#### [DevElf](README.md 'README') +### [DevElf\.ArgumentValidation](DevElf.ArgumentValidation.md 'DevElf\.ArgumentValidation').[EquatableExtensions](EquatableExtensions.md 'DevElf\.ArgumentValidation\.EquatableExtensions') + +## EquatableExtensions\.ThrowIfEqual Method + +| Overloads | | +| :--- | :--- | +| [ThrowIfEqual<T>\(this Nullable<T>, Nullable<T>, string\)](EquatableExtensions.ThrowIfEqual.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisSystem.Nullable_T_,System.Nullable_T_,string) 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this System\.Nullable\, System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this System\.Nullable\, System\.Nullable\, string\)\.value') is equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this System\.Nullable\, System\.Nullable\, string\)\.other')\. | +| [ThrowIfEqual<T>\(this Nullable<T>, T, string\)](EquatableExtensions.ThrowIfEqual.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisSystem.Nullable_T_,T,string) 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this System\.Nullable\, T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisSystem.Nullable_T_,T,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this System\.Nullable\, T, string\)\.value') is equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisSystem.Nullable_T_,T,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this System\.Nullable\, T, string\)\.other')\. | +| [ThrowIfEqual<T>\(this T, Nullable<T>, string\)](EquatableExtensions.ThrowIfEqual.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisT,System.Nullable_T_,string) 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this T, System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisT,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this T, System\.Nullable\, string\)\.value') is equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisT,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this T, System\.Nullable\, string\)\.other')\. | +| [ThrowIfEqual<T>\(this T, T, string\)](EquatableExtensions.ThrowIfEqual.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisT,T,string) 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this T, T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisT,T,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this T, T, string\)\.value') is equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisT,T,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this T, T, string\)\.other')\. | + + + +## EquatableExtensions\.ThrowIfEqual\\(this Nullable\, Nullable\, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this System\.Nullable\, System\.Nullable\, string\)\.value') is +equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this System\.Nullable\, System\.Nullable\, string\)\.other')\. + +```csharp +public static void ThrowIfEqual(this System.Nullable value, System.Nullable other, string parameterName=null) + where T : struct, System.IEquatable, System.ValueType, System.ValueType; +``` +#### Type parameters + + + +`T` + +The type of the objects to compare\. +#### Parameters + + + +`value` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[T](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).T 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this System\.Nullable\, System\.Nullable\, string\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The value to check\. + + + +`other` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[T](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).T 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this System\.Nullable\, System\.Nullable\, string\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The value to compare against\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the parameter being checked\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this System\.Nullable\, System\.Nullable\, string\)\.value') is equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this System\.Nullable\, System\.Nullable\, string\)\.other')\. + + + +## EquatableExtensions\.ThrowIfEqual\\(this Nullable\, T, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisSystem.Nullable_T_,T,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this System\.Nullable\, T, string\)\.value') is +equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisSystem.Nullable_T_,T,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this System\.Nullable\, T, string\)\.other')\. + +```csharp +public static void ThrowIfEqual(this System.Nullable value, T other, string parameterName=null) + where T : struct, System.IEquatable, System.ValueType, System.ValueType; +``` +#### Type parameters + + + +`T` + +The type of the objects to compare\. +#### Parameters + + + +`value` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[T](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisSystem.Nullable_T_,T,string).T 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this System\.Nullable\, T, string\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The value to check\. + + + +`other` [T](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisSystem.Nullable_T_,T,string).T 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this System\.Nullable\, T, string\)\.T') + +The value to compare against\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the parameter being checked\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisSystem.Nullable_T_,T,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this System\.Nullable\, T, string\)\.value') is equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisSystem.Nullable_T_,T,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this System\.Nullable\, T, string\)\.other')\. + + + +## EquatableExtensions\.ThrowIfEqual\\(this T, Nullable\, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisT,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this T, System\.Nullable\, string\)\.value') is +equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisT,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this T, System\.Nullable\, string\)\.other')\. + +```csharp +public static void ThrowIfEqual(this T value, System.Nullable other, string parameterName=null) + where T : struct, System.IEquatable, System.ValueType, System.ValueType; +``` +#### Type parameters + + + +`T` + +The type of the objects to compare\. +#### Parameters + + + +`value` [T](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisT,System.Nullable_T_,string).T 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this T, System\.Nullable\, string\)\.T') + +The value to check\. + + + +`other` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[T](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisT,System.Nullable_T_,string).T 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this T, System\.Nullable\, string\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The value to compare against\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the parameter being checked\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisT,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this T, System\.Nullable\, string\)\.value') is equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisT,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this T, System\.Nullable\, string\)\.other')\. + + + +## EquatableExtensions\.ThrowIfEqual\\(this T, T, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisT,T,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this T, T, string\)\.value') is +equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisT,T,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this T, T, string\)\.other')\. + +```csharp +public static void ThrowIfEqual(this T? value, T? other, string parameterName=null) + where T : System.IEquatable; +``` +#### Type parameters + + + +`T` + +The type of the objects to compare\. +#### Parameters + + + +`value` [T](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisT,T,string).T 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this T, T, string\)\.T') + +The value to check\. + + + +`other` [T](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisT,T,string).T 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this T, T, string\)\.T') + +The value to compare against\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the parameter being checked\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisT,T,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this T, T, string\)\.value') is equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisT,T,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this T, T, string\)\.other')\. \ No newline at end of file diff --git a/docs/api/DevElf/EquatableExtensions.ThrowIfNotEqual.md b/docs/api/DevElf/EquatableExtensions.ThrowIfNotEqual.md new file mode 100644 index 0000000..ec00416 --- /dev/null +++ b/docs/api/DevElf/EquatableExtensions.ThrowIfNotEqual.md @@ -0,0 +1,183 @@ +#### [DevElf](README.md 'README') +### [DevElf\.ArgumentValidation](DevElf.ArgumentValidation.md 'DevElf\.ArgumentValidation').[EquatableExtensions](EquatableExtensions.md 'DevElf\.ArgumentValidation\.EquatableExtensions') + +## EquatableExtensions\.ThrowIfNotEqual Method + +| Overloads | | +| :--- | :--- | +| [ThrowIfNotEqual<T>\(this Nullable<T>, Nullable<T>, string\)](EquatableExtensions.ThrowIfNotEqual.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisSystem.Nullable_T_,System.Nullable_T_,string) 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this System\.Nullable\, System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this System\.Nullable\, System\.Nullable\, string\)\.value') is not equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this System\.Nullable\, System\.Nullable\, string\)\.other')\. | +| [ThrowIfNotEqual<T>\(this Nullable<T>, T, string\)](EquatableExtensions.ThrowIfNotEqual.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisSystem.Nullable_T_,T,string) 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this System\.Nullable\, T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisSystem.Nullable_T_,T,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this System\.Nullable\, T, string\)\.value') is not equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisSystem.Nullable_T_,T,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this System\.Nullable\, T, string\)\.other')\. | +| [ThrowIfNotEqual<T>\(this T, Nullable<T>, string\)](EquatableExtensions.ThrowIfNotEqual.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisT,System.Nullable_T_,string) 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this T, System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisT,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this T, System\.Nullable\, string\)\.value') is not equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisT,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this T, System\.Nullable\, string\)\.other')\. | +| [ThrowIfNotEqual<T>\(this T, T, string\)](EquatableExtensions.ThrowIfNotEqual.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisT,T,string) 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this T, T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisT,T,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this T, T, string\)\.value') is not equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisT,T,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this T, T, string\)\.other')\. | + + + +## EquatableExtensions\.ThrowIfNotEqual\\(this Nullable\, Nullable\, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this System\.Nullable\, System\.Nullable\, string\)\.value') is +not equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this System\.Nullable\, System\.Nullable\, string\)\.other')\. + +```csharp +public static void ThrowIfNotEqual(this System.Nullable value, System.Nullable other, string parameterName=null) + where T : struct, System.IEquatable, System.ValueType, System.ValueType; +``` +#### Type parameters + + + +`T` + +The type of the objects to compare\. +#### Parameters + + + +`value` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[T](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).T 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this System\.Nullable\, System\.Nullable\, string\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The value to check\. + + + +`other` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[T](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).T 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this System\.Nullable\, System\.Nullable\, string\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The value to compare against\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the parameter being checked\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this System\.Nullable\, System\.Nullable\, string\)\.value') is not equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this System\.Nullable\, System\.Nullable\, string\)\.other')\. + + + +## EquatableExtensions\.ThrowIfNotEqual\\(this Nullable\, T, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisSystem.Nullable_T_,T,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this System\.Nullable\, T, string\)\.value') is +not equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisSystem.Nullable_T_,T,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this System\.Nullable\, T, string\)\.other')\. + +```csharp +public static void ThrowIfNotEqual(this System.Nullable value, T other, string parameterName=null) + where T : struct, System.IEquatable, System.ValueType, System.ValueType; +``` +#### Type parameters + + + +`T` + +The type of the objects to compare\. +#### Parameters + + + +`value` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[T](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisSystem.Nullable_T_,T,string).T 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this System\.Nullable\, T, string\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The value to check\. + + + +`other` [T](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisSystem.Nullable_T_,T,string).T 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this System\.Nullable\, T, string\)\.T') + +The value to compare against\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the parameter being checked\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisSystem.Nullable_T_,T,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this System\.Nullable\, T, string\)\.value') is not equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisSystem.Nullable_T_,T,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this System\.Nullable\, T, string\)\.other')\. + + + +## EquatableExtensions\.ThrowIfNotEqual\\(this T, Nullable\, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisT,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this T, System\.Nullable\, string\)\.value') is +not equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisT,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this T, System\.Nullable\, string\)\.other')\. + +```csharp +public static void ThrowIfNotEqual(this T value, System.Nullable other, string parameterName=null) + where T : struct, System.IEquatable, System.ValueType, System.ValueType; +``` +#### Type parameters + + + +`T` + +The type of the objects to compare\. +#### Parameters + + + +`value` [T](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisT,System.Nullable_T_,string).T 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this T, System\.Nullable\, string\)\.T') + +The value to check\. + + + +`other` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[T](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisT,System.Nullable_T_,string).T 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this T, System\.Nullable\, string\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The value to compare against\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the parameter being checked\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisT,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this T, System\.Nullable\, string\)\.value') is not equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisT,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this T, System\.Nullable\, string\)\.other')\. + + + +## EquatableExtensions\.ThrowIfNotEqual\\(this T, T, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisT,T,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this T, T, string\)\.value') is +not equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisT,T,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this T, T, string\)\.other')\. + +```csharp +public static void ThrowIfNotEqual(this T? value, T? other, string parameterName=null) + where T : System.IEquatable; +``` +#### Type parameters + + + +`T` + +The type of the objects to compare\. +#### Parameters + + + +`value` [T](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisT,T,string).T 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this T, T, string\)\.T') + +The value to check\. + + + +`other` [T](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisT,T,string).T 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this T, T, string\)\.T') + +The value to compare against\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the parameter being checked\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisT,T,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this T, T, string\)\.value') is not equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisT,T,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this T, T, string\)\.other')\. \ No newline at end of file diff --git a/docs/api/DevElf/EquatableExtensions.md b/docs/api/DevElf/EquatableExtensions.md new file mode 100644 index 0000000..b68120e --- /dev/null +++ b/docs/api/DevElf/EquatableExtensions.md @@ -0,0 +1,23 @@ +#### [DevElf](README.md 'README') +### [DevElf\.ArgumentValidation](DevElf.ArgumentValidation.md 'DevElf\.ArgumentValidation') + +## EquatableExtensions Class + +Provides extension methods for [System\.IEquatable<>](https://learn.microsoft.com/en-us/dotnet/api/system.iequatable-1 'System\.IEquatable\`1') types\. + +```csharp +public static class EquatableExtensions +``` + +Inheritance [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') 🡒 EquatableExtensions + +| Methods | | +| :--- | :--- | +| [ThrowIfEqual<T>\(this Nullable<T>, Nullable<T>, string\)](EquatableExtensions.ThrowIfEqual.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisSystem.Nullable_T_,System.Nullable_T_,string) 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this System\.Nullable\, System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this System\.Nullable\, System\.Nullable\, string\)\.value') is equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this System\.Nullable\, System\.Nullable\, string\)\.other')\. | +| [ThrowIfEqual<T>\(this Nullable<T>, T, string\)](EquatableExtensions.ThrowIfEqual.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisSystem.Nullable_T_,T,string) 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this System\.Nullable\, T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisSystem.Nullable_T_,T,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this System\.Nullable\, T, string\)\.value') is equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisSystem.Nullable_T_,T,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this System\.Nullable\, T, string\)\.other')\. | +| [ThrowIfEqual<T>\(this T, Nullable<T>, string\)](EquatableExtensions.ThrowIfEqual.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisT,System.Nullable_T_,string) 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this T, System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisT,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this T, System\.Nullable\, string\)\.value') is equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisT,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this T, System\.Nullable\, string\)\.other')\. | +| [ThrowIfEqual<T>\(this T, T, string\)](EquatableExtensions.ThrowIfEqual.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisT,T,string) 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this T, T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisT,T,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this T, T, string\)\.value') is equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfEqual_T_(thisT,T,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfEqual\\(this T, T, string\)\.other')\. | +| [ThrowIfNotEqual<T>\(this Nullable<T>, Nullable<T>, string\)](EquatableExtensions.ThrowIfNotEqual.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisSystem.Nullable_T_,System.Nullable_T_,string) 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this System\.Nullable\, System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this System\.Nullable\, System\.Nullable\, string\)\.value') is not equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisSystem.Nullable_T_,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this System\.Nullable\, System\.Nullable\, string\)\.other')\. | +| [ThrowIfNotEqual<T>\(this Nullable<T>, T, string\)](EquatableExtensions.ThrowIfNotEqual.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisSystem.Nullable_T_,T,string) 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this System\.Nullable\, T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisSystem.Nullable_T_,T,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this System\.Nullable\, T, string\)\.value') is not equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisSystem.Nullable_T_,T,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this System\.Nullable\, T, string\)\.other')\. | +| [ThrowIfNotEqual<T>\(this T, Nullable<T>, string\)](EquatableExtensions.ThrowIfNotEqual.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisT,System.Nullable_T_,string) 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this T, System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisT,System.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this T, System\.Nullable\, string\)\.value') is not equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisT,System.Nullable_T_,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this T, System\.Nullable\, string\)\.other')\. | +| [ThrowIfNotEqual<T>\(this T, T, string\)](EquatableExtensions.ThrowIfNotEqual.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisT,T,string) 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this T, T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified [value](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisT,T,string).value 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this T, T, string\)\.value') is not equal to [other](EquatableExtensions.md#DevElf.ArgumentValidation.EquatableExtensions.ThrowIfNotEqual_T_(thisT,T,string).other 'DevElf\.ArgumentValidation\.EquatableExtensions\.ThrowIfNotEqual\\(this T, T, string\)\.other')\. | diff --git a/docs/api/DevElf/FrozenTimeProvider.FrozenTimeProvider.md b/docs/api/DevElf/FrozenTimeProvider.FrozenTimeProvider.md new file mode 100644 index 0000000..501001d --- /dev/null +++ b/docs/api/DevElf/FrozenTimeProvider.FrozenTimeProvider.md @@ -0,0 +1,50 @@ +#### [DevElf](README.md 'README') +### [DevElf](DevElf.md 'DevElf').[FrozenTimeProvider](FrozenTimeProvider.md 'DevElf\.FrozenTimeProvider') + +## FrozenTimeProvider Constructors + +| Overloads | | +| :--- | :--- | +| [FrozenTimeProvider\(DateTimeOffset\)](FrozenTimeProvider.FrozenTimeProvider.md#DevElf.FrozenTimeProvider.FrozenTimeProvider(System.DateTimeOffset) 'DevElf\.FrozenTimeProvider\.FrozenTimeProvider\(System\.DateTimeOffset\)') | Creates a new instance that will always return the provided instant in UTC\. The provided [System\.DateTimeOffset](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset 'System\.DateTimeOffset') is converted to UTC internally\. | +| [FrozenTimeProvider\(TimeProvider\)](FrozenTimeProvider.FrozenTimeProvider.md#DevElf.FrozenTimeProvider.FrozenTimeProvider(System.TimeProvider) 'DevElf\.FrozenTimeProvider\.FrozenTimeProvider\(System\.TimeProvider\)') | Creates a new instance that is frozen to the current value of the specified [System\.TimeProvider](https://learn.microsoft.com/en-us/dotnet/api/system.timeprovider 'System\.TimeProvider')\. | + + + +## FrozenTimeProvider\(DateTimeOffset\) Constructor + +Creates a new instance that will always return the provided instant in UTC\. +The provided [System\.DateTimeOffset](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset 'System\.DateTimeOffset') is converted to UTC internally\. + +```csharp +public FrozenTimeProvider(System.DateTimeOffset now); +``` +#### Parameters + + + +`now` [System\.DateTimeOffset](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset 'System\.DateTimeOffset') + +The instant to freeze\. + + + +## FrozenTimeProvider\(TimeProvider\) Constructor + +Creates a new instance that is frozen to the current value of the +specified [System\.TimeProvider](https://learn.microsoft.com/en-us/dotnet/api/system.timeprovider 'System\.TimeProvider')\. + +```csharp +public FrozenTimeProvider(System.TimeProvider timeProvider); +``` +#### Parameters + + + +`timeProvider` [System\.TimeProvider](https://learn.microsoft.com/en-us/dotnet/api/system.timeprovider 'System\.TimeProvider') + +The source time provider used to obtain the instant to freeze\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +If [timeProvider](FrozenTimeProvider.md#DevElf.FrozenTimeProvider.FrozenTimeProvider(System.TimeProvider).timeProvider 'DevElf\.FrozenTimeProvider\.FrozenTimeProvider\(System\.TimeProvider\)\.timeProvider') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. \ No newline at end of file diff --git a/docs/api/DevElf/FrozenTimeProvider.GetUtcNow().md b/docs/api/DevElf/FrozenTimeProvider.GetUtcNow().md new file mode 100644 index 0000000..2687c39 --- /dev/null +++ b/docs/api/DevElf/FrozenTimeProvider.GetUtcNow().md @@ -0,0 +1,14 @@ +#### [DevElf](README.md 'README') +### [DevElf](DevElf.md 'DevElf').[FrozenTimeProvider](FrozenTimeProvider.md 'DevElf\.FrozenTimeProvider') + +## FrozenTimeProvider\.GetUtcNow\(\) Method + +Returns the frozen instant as a UTC [System\.DateTimeOffset](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset 'System\.DateTimeOffset')\. + +```csharp +public override System.DateTimeOffset GetUtcNow(); +``` + +#### Returns +[System\.DateTimeOffset](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset 'System\.DateTimeOffset') +The frozen UTC instant\. \ No newline at end of file diff --git a/docs/api/DevElf/FrozenTimeProvider.md b/docs/api/DevElf/FrozenTimeProvider.md new file mode 100644 index 0000000..4658473 --- /dev/null +++ b/docs/api/DevElf/FrozenTimeProvider.md @@ -0,0 +1,22 @@ +#### [DevElf](README.md 'README') +### [DevElf](DevElf.md 'DevElf') + +## FrozenTimeProvider Class + +A [System\.TimeProvider](https://learn.microsoft.com/en-us/dotnet/api/system.timeprovider 'System\.TimeProvider') that always returns a fixed point in time\. +Useful for tests and deterministic time\-dependent logic\. + +```csharp +public sealed class FrozenTimeProvider : System.TimeProvider +``` + +Inheritance [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') 🡒 [System\.TimeProvider](https://learn.microsoft.com/en-us/dotnet/api/system.timeprovider 'System\.TimeProvider') 🡒 FrozenTimeProvider + +| Constructors | | +| :--- | :--- | +| [FrozenTimeProvider\(DateTimeOffset\)](FrozenTimeProvider.FrozenTimeProvider.md#DevElf.FrozenTimeProvider.FrozenTimeProvider(System.DateTimeOffset) 'DevElf\.FrozenTimeProvider\.FrozenTimeProvider\(System\.DateTimeOffset\)') | Creates a new instance that will always return the provided instant in UTC\. The provided [System\.DateTimeOffset](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset 'System\.DateTimeOffset') is converted to UTC internally\. | +| [FrozenTimeProvider\(TimeProvider\)](FrozenTimeProvider.FrozenTimeProvider.md#DevElf.FrozenTimeProvider.FrozenTimeProvider(System.TimeProvider) 'DevElf\.FrozenTimeProvider\.FrozenTimeProvider\(System\.TimeProvider\)') | Creates a new instance that is frozen to the current value of the specified [System\.TimeProvider](https://learn.microsoft.com/en-us/dotnet/api/system.timeprovider 'System\.TimeProvider')\. | + +| Methods | | +| :--- | :--- | +| [GetUtcNow\(\)](FrozenTimeProvider.GetUtcNow().md 'DevElf\.FrozenTimeProvider\.GetUtcNow\(\)') | Returns the frozen instant as a UTC [System\.DateTimeOffset](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset 'System\.DateTimeOffset')\. | diff --git a/docs/api/DevElf/GenericExtensions.ThrowIfNull.md b/docs/api/DevElf/GenericExtensions.ThrowIfNull.md new file mode 100644 index 0000000..1f7ac31 --- /dev/null +++ b/docs/api/DevElf/GenericExtensions.ThrowIfNull.md @@ -0,0 +1,87 @@ +#### [DevElf](README.md 'README') +### [DevElf\.ArgumentValidation](DevElf.ArgumentValidation.md 'DevElf\.ArgumentValidation').[GenericExtensions](GenericExtensions.md 'DevElf\.ArgumentValidation\.GenericExtensions') + +## GenericExtensions\.ThrowIfNull Method + +| Overloads | | +| :--- | :--- | +| [ThrowIfNull<T>\(this Nullable<T>, string\)](GenericExtensions.ThrowIfNull.md#DevElf.ArgumentValidation.GenericExtensions.ThrowIfNull_T_(thisSystem.Nullable_T_,string) 'DevElf\.ArgumentValidation\.GenericExtensions\.ThrowIfNull\\(this System\.Nullable\, string\)') | Throws an [System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') when [argument](GenericExtensions.md#DevElf.ArgumentValidation.GenericExtensions.ThrowIfNull_T_(thisSystem.Nullable_T_,string).argument 'DevElf\.ArgumentValidation\.GenericExtensions\.ThrowIfNull\\(this System\.Nullable\, string\)\.argument') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. Applies to nullable value types\. | +| [ThrowIfNull<T>\(this T, string\)](GenericExtensions.ThrowIfNull.md#DevElf.ArgumentValidation.GenericExtensions.ThrowIfNull_T_(thisT,string) 'DevElf\.ArgumentValidation\.GenericExtensions\.ThrowIfNull\\(this T, string\)') | Throws an [System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') when [argument](GenericExtensions.md#DevElf.ArgumentValidation.GenericExtensions.ThrowIfNull_T_(thisT,string).argument 'DevElf\.ArgumentValidation\.GenericExtensions\.ThrowIfNull\\(this T, string\)\.argument') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. Applies to reference types\. | + + + +## GenericExtensions\.ThrowIfNull\\(this Nullable\, string\) Method + +Throws an [System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') when [argument](GenericExtensions.md#DevElf.ArgumentValidation.GenericExtensions.ThrowIfNull_T_(thisSystem.Nullable_T_,string).argument 'DevElf\.ArgumentValidation\.GenericExtensions\.ThrowIfNull\\(this System\.Nullable\, string\)\.argument') is +[null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. Applies to nullable value types\. + +```csharp +public static void ThrowIfNull(this System.Nullable argument, string parameterName=null) + where T : struct, System.ValueType, System.ValueType; +``` +#### Type parameters + + + +`T` + +The value type of the argument to validate\. +#### Parameters + + + +`argument` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[T](GenericExtensions.md#DevElf.ArgumentValidation.GenericExtensions.ThrowIfNull_T_(thisSystem.Nullable_T_,string).T 'DevElf\.ArgumentValidation\.GenericExtensions\.ThrowIfNull\\(this System\.Nullable\, string\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The argument to validate\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the parameter\. This is supplied automatically by the compiler when the method +is used as an extension method because of the [System\.Runtime\.CompilerServices\.CallerArgumentExpressionAttribute](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.callerargumentexpressionattribute 'System\.Runtime\.CompilerServices\.CallerArgumentExpressionAttribute') +on this parameter\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +Thrown when [argument](GenericExtensions.md#DevElf.ArgumentValidation.GenericExtensions.ThrowIfNull_T_(thisSystem.Nullable_T_,string).argument 'DevElf\.ArgumentValidation\.GenericExtensions\.ThrowIfNull\\(this System\.Nullable\, string\)\.argument') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + + + +## GenericExtensions\.ThrowIfNull\\(this T, string\) Method + +Throws an [System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') when [argument](GenericExtensions.md#DevElf.ArgumentValidation.GenericExtensions.ThrowIfNull_T_(thisT,string).argument 'DevElf\.ArgumentValidation\.GenericExtensions\.ThrowIfNull\\(this T, string\)\.argument') is +[null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. Applies to reference types\. + +```csharp +public static void ThrowIfNull(this T? argument, string parameterName=null) + where T : class; +``` +#### Type parameters + + + +`T` + +The reference type of the argument to validate\. +#### Parameters + + + +`argument` [T](GenericExtensions.md#DevElf.ArgumentValidation.GenericExtensions.ThrowIfNull_T_(thisT,string).T 'DevElf\.ArgumentValidation\.GenericExtensions\.ThrowIfNull\\(this T, string\)\.T') + +The argument to validate\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the parameter\. This is supplied automatically by the compiler when the method +is used as an extension method because of the [System\.Runtime\.CompilerServices\.CallerArgumentExpressionAttribute](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.callerargumentexpressionattribute 'System\.Runtime\.CompilerServices\.CallerArgumentExpressionAttribute') +on this parameter\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +Thrown when [argument](GenericExtensions.md#DevElf.ArgumentValidation.GenericExtensions.ThrowIfNull_T_(thisT,string).argument 'DevElf\.ArgumentValidation\.GenericExtensions\.ThrowIfNull\\(this T, string\)\.argument') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. \ No newline at end of file diff --git a/docs/api/DevElf/GenericExtensions.md b/docs/api/DevElf/GenericExtensions.md new file mode 100644 index 0000000..67e9f0c --- /dev/null +++ b/docs/api/DevElf/GenericExtensions.md @@ -0,0 +1,17 @@ +#### [DevElf](README.md 'README') +### [DevElf\.ArgumentValidation](DevElf.ArgumentValidation.md 'DevElf\.ArgumentValidation') + +## GenericExtensions Class + +Provides argument validation helpers for reference types and nullable value types\. + +```csharp +public static class GenericExtensions +``` + +Inheritance [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') 🡒 GenericExtensions + +| Methods | | +| :--- | :--- | +| [ThrowIfNull<T>\(this Nullable<T>, string\)](GenericExtensions.ThrowIfNull.md#DevElf.ArgumentValidation.GenericExtensions.ThrowIfNull_T_(thisSystem.Nullable_T_,string) 'DevElf\.ArgumentValidation\.GenericExtensions\.ThrowIfNull\\(this System\.Nullable\, string\)') | Throws an [System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') when [argument](GenericExtensions.md#DevElf.ArgumentValidation.GenericExtensions.ThrowIfNull_T_(thisSystem.Nullable_T_,string).argument 'DevElf\.ArgumentValidation\.GenericExtensions\.ThrowIfNull\\(this System\.Nullable\, string\)\.argument') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. Applies to nullable value types\. | +| [ThrowIfNull<T>\(this T, string\)](GenericExtensions.ThrowIfNull.md#DevElf.ArgumentValidation.GenericExtensions.ThrowIfNull_T_(thisT,string) 'DevElf\.ArgumentValidation\.GenericExtensions\.ThrowIfNull\\(this T, string\)') | Throws an [System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') when [argument](GenericExtensions.md#DevElf.ArgumentValidation.GenericExtensions.ThrowIfNull_T_(thisT,string).argument 'DevElf\.ArgumentValidation\.GenericExtensions\.ThrowIfNull\\(this T, string\)\.argument') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. Applies to reference types\. | diff --git a/docs/api/DevElf/LambdaExtensions.UnwrapAndReThrow.md b/docs/api/DevElf/LambdaExtensions.UnwrapAndReThrow.md new file mode 100644 index 0000000..d6114a3 --- /dev/null +++ b/docs/api/DevElf/LambdaExtensions.UnwrapAndReThrow.md @@ -0,0 +1,74 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[LambdaExtensions](LambdaExtensions.md 'DevElf\.Extensions\.LambdaExtensions') + +## LambdaExtensions\.UnwrapAndReThrow Method + +| Overloads | | +| :--- | :--- | +| [UnwrapAndReThrow\(this Action\)](LambdaExtensions.UnwrapAndReThrow.md#DevElf.Extensions.LambdaExtensions.UnwrapAndReThrow(thisSystem.Action) 'DevElf\.Extensions\.LambdaExtensions\.UnwrapAndReThrow\(this System\.Action\)') | Wraps an [System\.Action](https://learn.microsoft.com/en-us/dotnet/api/system.action 'System\.Action') so that if it throws an exception that contains inner exceptions, the innermost exception is re\-thrown while preserving the original stack trace\. | +| [UnwrapAndReThrow<T>\(this Func<T>\)](LambdaExtensions.UnwrapAndReThrow.md#DevElf.Extensions.LambdaExtensions.UnwrapAndReThrow_T_(thisSystem.Func_T_) 'DevElf\.Extensions\.LambdaExtensions\.UnwrapAndReThrow\\(this System\.Func\\)') | Wraps a [System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1') so that if it throws an exception that contains inner exceptions, the innermost exception is re\-thrown while preserving the original stack trace\. | + + + +## LambdaExtensions\.UnwrapAndReThrow\(this Action\) Method + +Wraps an [System\.Action](https://learn.microsoft.com/en-us/dotnet/api/system.action 'System\.Action') so that if it throws an exception that contains +inner exceptions, the innermost exception is re\-thrown while preserving the +original stack trace\. + +```csharp +public static System.Action UnwrapAndReThrow(this System.Action action); +``` +#### Parameters + + + +`action` [System\.Action](https://learn.microsoft.com/en-us/dotnet/api/system.action 'System\.Action') + +The action to execute\. + +#### Returns +[System\.Action](https://learn.microsoft.com/en-us/dotnet/api/system.action 'System\.Action') +A new [System\.Action](https://learn.microsoft.com/en-us/dotnet/api/system.action 'System\.Action') that executes [action](LambdaExtensions.md#DevElf.Extensions.LambdaExtensions.UnwrapAndReThrow(thisSystem.Action).action 'DevElf\.Extensions\.LambdaExtensions\.UnwrapAndReThrow\(this System\.Action\)\.action') and, when an +exception occurs, re\-throws the innermost exception\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +Thrown when [action](LambdaExtensions.md#DevElf.Extensions.LambdaExtensions.UnwrapAndReThrow(thisSystem.Action).action 'DevElf\.Extensions\.LambdaExtensions\.UnwrapAndReThrow\(this System\.Action\)\.action') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + + + +## LambdaExtensions\.UnwrapAndReThrow\\(this Func\\) Method + +Wraps a [System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1') so that if it throws an exception that +contains inner exceptions, the innermost exception is re\-thrown while preserving +the original stack trace\. + +```csharp +public static System.Func UnwrapAndReThrow(this System.Func function); +``` +#### Type parameters + + + +`T` + +The result type of the function\. +#### Parameters + + + +`function` [System\.Func<](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')[T](LambdaExtensions.md#DevElf.Extensions.LambdaExtensions.UnwrapAndReThrow_T_(thisSystem.Func_T_).T 'DevElf\.Extensions\.LambdaExtensions\.UnwrapAndReThrow\\(this System\.Func\\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1') + +The function to execute\. + +#### Returns +[System\.Func<](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')[T](LambdaExtensions.md#DevElf.Extensions.LambdaExtensions.UnwrapAndReThrow_T_(thisSystem.Func_T_).T 'DevElf\.Extensions\.LambdaExtensions\.UnwrapAndReThrow\\(this System\.Func\\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1') +A new [System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1') that executes [function](LambdaExtensions.md#DevElf.Extensions.LambdaExtensions.UnwrapAndReThrow_T_(thisSystem.Func_T_).function 'DevElf\.Extensions\.LambdaExtensions\.UnwrapAndReThrow\\(this System\.Func\\)\.function') and, when an +exception occurs, re\-throws the innermost exception\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +Thrown when [function](LambdaExtensions.md#DevElf.Extensions.LambdaExtensions.UnwrapAndReThrow_T_(thisSystem.Func_T_).function 'DevElf\.Extensions\.LambdaExtensions\.UnwrapAndReThrow\\(this System\.Func\\)\.function') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. \ No newline at end of file diff --git a/docs/api/DevElf/LambdaExtensions.md b/docs/api/DevElf/LambdaExtensions.md new file mode 100644 index 0000000..be639f6 --- /dev/null +++ b/docs/api/DevElf/LambdaExtensions.md @@ -0,0 +1,17 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions') + +## LambdaExtensions Class + +Provides extension methods for delegates\. + +```csharp +public static class LambdaExtensions +``` + +Inheritance [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') 🡒 LambdaExtensions + +| Methods | | +| :--- | :--- | +| [UnwrapAndReThrow\(this Action\)](LambdaExtensions.UnwrapAndReThrow.md#DevElf.Extensions.LambdaExtensions.UnwrapAndReThrow(thisSystem.Action) 'DevElf\.Extensions\.LambdaExtensions\.UnwrapAndReThrow\(this System\.Action\)') | Wraps an [System\.Action](https://learn.microsoft.com/en-us/dotnet/api/system.action 'System\.Action') so that if it throws an exception that contains inner exceptions, the innermost exception is re\-thrown while preserving the original stack trace\. | +| [UnwrapAndReThrow<T>\(this Func<T>\)](LambdaExtensions.UnwrapAndReThrow.md#DevElf.Extensions.LambdaExtensions.UnwrapAndReThrow_T_(thisSystem.Func_T_) 'DevElf\.Extensions\.LambdaExtensions\.UnwrapAndReThrow\\(this System\.Func\\)') | Wraps a [System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1') so that if it throws an exception that contains inner exceptions, the innermost exception is re\-thrown while preserving the original stack trace\. | diff --git a/docs/api/DevElf/NumberBaseExtensions.ThrowIfNegative.md b/docs/api/DevElf/NumberBaseExtensions.ThrowIfNegative.md new file mode 100644 index 0000000..e52c5b3 --- /dev/null +++ b/docs/api/DevElf/NumberBaseExtensions.ThrowIfNegative.md @@ -0,0 +1,83 @@ +#### [DevElf](README.md 'README') +### [DevElf\.ArgumentValidation](DevElf.ArgumentValidation.md 'DevElf\.ArgumentValidation').[NumberBaseExtensions](NumberBaseExtensions.md 'DevElf\.ArgumentValidation\.NumberBaseExtensions') + +## NumberBaseExtensions\.ThrowIfNegative Method + +| Overloads | | +| :--- | :--- | +| [ThrowIfNegative<T>\(this Nullable<T>, string\)](NumberBaseExtensions.ThrowIfNegative.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfNegative_T_(thisSystem.Nullable_T_,string) 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfNegative\\(this System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified value is negative\. | +| [ThrowIfNegative<T>\(this T, string\)](NumberBaseExtensions.ThrowIfNegative.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfNegative_T_(thisT,string) 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfNegative\\(this T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified value is negative\. | + + + +## NumberBaseExtensions\.ThrowIfNegative\\(this Nullable\, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified value is negative\. + +```csharp +public static void ThrowIfNegative(this System.Nullable value, string parameterName=null) + where T : struct, System.Numerics.INumberBase, System.ValueType, System.ValueType; +``` +#### Type parameters + + + +`T` + +The type of the value to check, which must be a struct and implement [System\.Numerics\.INumberBase<>](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.inumberbase-1 'System\.Numerics\.INumberBase\`1')\. +#### Parameters + + + +`value` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[T](NumberBaseExtensions.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfNegative_T_(thisSystem.Nullable_T_,string).T 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfNegative\\(this System\.Nullable\, string\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The value to check\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the parameter being checked\. This is automatically captured from the expression +passed as the [value](NumberBaseExtensions.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfNegative_T_(thisSystem.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfNegative\\(this System\.Nullable\, string\)\.value')\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when the [value](NumberBaseExtensions.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfNegative_T_(thisSystem.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfNegative\\(this System\.Nullable\, string\)\.value') is negative\. + + + +## NumberBaseExtensions\.ThrowIfNegative\\(this T, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified value is negative\. + +```csharp +public static void ThrowIfNegative(this T? value, string parameterName=null) + where T : System.Numerics.INumberBase; +``` +#### Type parameters + + + +`T` + +The type of the value to check, which must implement [System\.Numerics\.INumberBase<>](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.inumberbase-1 'System\.Numerics\.INumberBase\`1')\. +#### Parameters + + + +`value` [T](NumberBaseExtensions.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfNegative_T_(thisT,string).T 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfNegative\\(this T, string\)\.T') + +The value to check\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the parameter being checked\. This is automatically captured from the expression +passed as the [value](NumberBaseExtensions.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfNegative_T_(thisT,string).value 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfNegative\\(this T, string\)\.value')\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when the [value](NumberBaseExtensions.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfNegative_T_(thisT,string).value 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfNegative\\(this T, string\)\.value') is negative\. \ No newline at end of file diff --git a/docs/api/DevElf/NumberBaseExtensions.ThrowIfNegativeOrZero.md b/docs/api/DevElf/NumberBaseExtensions.ThrowIfNegativeOrZero.md new file mode 100644 index 0000000..3ebd733 --- /dev/null +++ b/docs/api/DevElf/NumberBaseExtensions.ThrowIfNegativeOrZero.md @@ -0,0 +1,83 @@ +#### [DevElf](README.md 'README') +### [DevElf\.ArgumentValidation](DevElf.ArgumentValidation.md 'DevElf\.ArgumentValidation').[NumberBaseExtensions](NumberBaseExtensions.md 'DevElf\.ArgumentValidation\.NumberBaseExtensions') + +## NumberBaseExtensions\.ThrowIfNegativeOrZero Method + +| Overloads | | +| :--- | :--- | +| [ThrowIfNegativeOrZero<T>\(this Nullable<T>, string\)](NumberBaseExtensions.ThrowIfNegativeOrZero.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfNegativeOrZero_T_(thisSystem.Nullable_T_,string) 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfNegativeOrZero\\(this System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified value is negative or zero\. | +| [ThrowIfNegativeOrZero<T>\(this T, string\)](NumberBaseExtensions.ThrowIfNegativeOrZero.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfNegativeOrZero_T_(thisT,string) 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfNegativeOrZero\\(this T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified value is negative or zero\. | + + + +## NumberBaseExtensions\.ThrowIfNegativeOrZero\\(this Nullable\, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified value is negative or zero\. + +```csharp +public static void ThrowIfNegativeOrZero(this System.Nullable value, string parameterName=null) + where T : struct, System.Numerics.INumberBase, System.ValueType, System.ValueType; +``` +#### Type parameters + + + +`T` + +The type of the value to check, which must be a struct and implement [System\.Numerics\.INumberBase<>](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.inumberbase-1 'System\.Numerics\.INumberBase\`1')\. +#### Parameters + + + +`value` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[T](NumberBaseExtensions.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfNegativeOrZero_T_(thisSystem.Nullable_T_,string).T 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfNegativeOrZero\\(this System\.Nullable\, string\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The value to check\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the parameter being checked\. This is automatically captured from the expression +passed as the [value](NumberBaseExtensions.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfNegativeOrZero_T_(thisSystem.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfNegativeOrZero\\(this System\.Nullable\, string\)\.value')\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when the [value](NumberBaseExtensions.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfNegativeOrZero_T_(thisSystem.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfNegativeOrZero\\(this System\.Nullable\, string\)\.value') is negative or zero\. + + + +## NumberBaseExtensions\.ThrowIfNegativeOrZero\\(this T, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified value is negative or zero\. + +```csharp +public static void ThrowIfNegativeOrZero(this T? value, string parameterName=null) + where T : System.Numerics.INumberBase; +``` +#### Type parameters + + + +`T` + +The type of the value to check, which must implement [System\.Numerics\.INumberBase<>](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.inumberbase-1 'System\.Numerics\.INumberBase\`1')\. +#### Parameters + + + +`value` [T](NumberBaseExtensions.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfNegativeOrZero_T_(thisT,string).T 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfNegativeOrZero\\(this T, string\)\.T') + +The value to check\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the parameter being checked\. This is automatically captured from the expression +passed as the [value](NumberBaseExtensions.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfNegativeOrZero_T_(thisT,string).value 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfNegativeOrZero\\(this T, string\)\.value')\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when the [value](NumberBaseExtensions.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfNegativeOrZero_T_(thisT,string).value 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfNegativeOrZero\\(this T, string\)\.value') is negative or zero\. \ No newline at end of file diff --git a/docs/api/DevElf/NumberBaseExtensions.ThrowIfPositive.md b/docs/api/DevElf/NumberBaseExtensions.ThrowIfPositive.md new file mode 100644 index 0000000..c75848e --- /dev/null +++ b/docs/api/DevElf/NumberBaseExtensions.ThrowIfPositive.md @@ -0,0 +1,83 @@ +#### [DevElf](README.md 'README') +### [DevElf\.ArgumentValidation](DevElf.ArgumentValidation.md 'DevElf\.ArgumentValidation').[NumberBaseExtensions](NumberBaseExtensions.md 'DevElf\.ArgumentValidation\.NumberBaseExtensions') + +## NumberBaseExtensions\.ThrowIfPositive Method + +| Overloads | | +| :--- | :--- | +| [ThrowIfPositive<T>\(this Nullable<T>, string\)](NumberBaseExtensions.ThrowIfPositive.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfPositive_T_(thisSystem.Nullable_T_,string) 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfPositive\\(this System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified value is positive\. | +| [ThrowIfPositive<T>\(this T, string\)](NumberBaseExtensions.ThrowIfPositive.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfPositive_T_(thisT,string) 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfPositive\\(this T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified value is positive\. | + + + +## NumberBaseExtensions\.ThrowIfPositive\\(this Nullable\, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified value is positive\. + +```csharp +public static void ThrowIfPositive(this System.Nullable value, string parameterName=null) + where T : struct, System.Numerics.INumberBase, System.ValueType, System.ValueType; +``` +#### Type parameters + + + +`T` + +The type of the value to check, which must be a struct and implement [System\.Numerics\.INumberBase<>](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.inumberbase-1 'System\.Numerics\.INumberBase\`1')\. +#### Parameters + + + +`value` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[T](NumberBaseExtensions.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfPositive_T_(thisSystem.Nullable_T_,string).T 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfPositive\\(this System\.Nullable\, string\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The value to check\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the parameter being checked\. This is automatically captured from the expression +passed as the [value](NumberBaseExtensions.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfPositive_T_(thisSystem.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfPositive\\(this System\.Nullable\, string\)\.value')\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when the [value](NumberBaseExtensions.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfPositive_T_(thisSystem.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfPositive\\(this System\.Nullable\, string\)\.value') is positive\. + + + +## NumberBaseExtensions\.ThrowIfPositive\\(this T, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified value is positive\. + +```csharp +public static void ThrowIfPositive(this T? value, string parameterName=null) + where T : System.Numerics.INumberBase; +``` +#### Type parameters + + + +`T` + +The type of the value to check, which must implement [System\.Numerics\.INumberBase<>](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.inumberbase-1 'System\.Numerics\.INumberBase\`1')\. +#### Parameters + + + +`value` [T](NumberBaseExtensions.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfPositive_T_(thisT,string).T 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfPositive\\(this T, string\)\.T') + +The value to check\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the parameter being checked\. This is automatically captured from the expression +passed as the [value](NumberBaseExtensions.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfPositive_T_(thisT,string).value 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfPositive\\(this T, string\)\.value')\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when the [value](NumberBaseExtensions.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfPositive_T_(thisT,string).value 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfPositive\\(this T, string\)\.value') is positive\. \ No newline at end of file diff --git a/docs/api/DevElf/NumberBaseExtensions.ThrowIfZero.md b/docs/api/DevElf/NumberBaseExtensions.ThrowIfZero.md new file mode 100644 index 0000000..5061191 --- /dev/null +++ b/docs/api/DevElf/NumberBaseExtensions.ThrowIfZero.md @@ -0,0 +1,83 @@ +#### [DevElf](README.md 'README') +### [DevElf\.ArgumentValidation](DevElf.ArgumentValidation.md 'DevElf\.ArgumentValidation').[NumberBaseExtensions](NumberBaseExtensions.md 'DevElf\.ArgumentValidation\.NumberBaseExtensions') + +## NumberBaseExtensions\.ThrowIfZero Method + +| Overloads | | +| :--- | :--- | +| [ThrowIfZero<T>\(this Nullable<T>, string\)](NumberBaseExtensions.ThrowIfZero.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfZero_T_(thisSystem.Nullable_T_,string) 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfZero\\(this System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified value is zero\. | +| [ThrowIfZero<T>\(this T, string\)](NumberBaseExtensions.ThrowIfZero.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfZero_T_(thisT,string) 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfZero\\(this T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified value is zero\. | + + + +## NumberBaseExtensions\.ThrowIfZero\\(this Nullable\, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified value is zero\. + +```csharp +public static void ThrowIfZero(this System.Nullable value, string parameterName=null) + where T : struct, System.Numerics.INumberBase, System.ValueType, System.ValueType; +``` +#### Type parameters + + + +`T` + +The type of the value to check, which must be a struct and implement [System\.Numerics\.INumberBase<>](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.inumberbase-1 'System\.Numerics\.INumberBase\`1')\. +#### Parameters + + + +`value` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[T](NumberBaseExtensions.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfZero_T_(thisSystem.Nullable_T_,string).T 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfZero\\(this System\.Nullable\, string\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The value to check\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the parameter being checked\. This is automatically captured from the expression +passed as the [value](NumberBaseExtensions.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfZero_T_(thisSystem.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfZero\\(this System\.Nullable\, string\)\.value')\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when the [value](NumberBaseExtensions.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfZero_T_(thisSystem.Nullable_T_,string).value 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfZero\\(this System\.Nullable\, string\)\.value') is zero\. + + + +## NumberBaseExtensions\.ThrowIfZero\\(this T, string\) Method + +Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified value is zero\. + +```csharp +public static void ThrowIfZero(this T? value, string parameterName=null) + where T : System.Numerics.INumberBase; +``` +#### Type parameters + + + +`T` + +The type of the value to check, which must implement [System\.Numerics\.INumberBase<>](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.inumberbase-1 'System\.Numerics\.INumberBase\`1')\. +#### Parameters + + + +`value` [T](NumberBaseExtensions.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfZero_T_(thisT,string).T 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfZero\\(this T, string\)\.T') + +The value to check\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the parameter being checked\. This is automatically captured from the expression +passed as the [value](NumberBaseExtensions.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfZero_T_(thisT,string).value 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfZero\\(this T, string\)\.value')\. + +#### Exceptions + +[System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') +Thrown when the [value](NumberBaseExtensions.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfZero_T_(thisT,string).value 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfZero\\(this T, string\)\.value') is zero\. \ No newline at end of file diff --git a/docs/api/DevElf/NumberBaseExtensions.md b/docs/api/DevElf/NumberBaseExtensions.md new file mode 100644 index 0000000..40dc305 --- /dev/null +++ b/docs/api/DevElf/NumberBaseExtensions.md @@ -0,0 +1,23 @@ +#### [DevElf](README.md 'README') +### [DevElf\.ArgumentValidation](DevElf.ArgumentValidation.md 'DevElf\.ArgumentValidation') + +## NumberBaseExtensions Class + +Provides extension methods for validating arguments of type [System\.Numerics\.INumberBase<>](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.inumberbase-1 'System\.Numerics\.INumberBase\`1')\. + +```csharp +public static class NumberBaseExtensions +``` + +Inheritance [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') 🡒 NumberBaseExtensions + +| Methods | | +| :--- | :--- | +| [ThrowIfNegative<T>\(this Nullable<T>, string\)](NumberBaseExtensions.ThrowIfNegative.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfNegative_T_(thisSystem.Nullable_T_,string) 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfNegative\\(this System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified value is negative\. | +| [ThrowIfNegative<T>\(this T, string\)](NumberBaseExtensions.ThrowIfNegative.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfNegative_T_(thisT,string) 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfNegative\\(this T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified value is negative\. | +| [ThrowIfNegativeOrZero<T>\(this Nullable<T>, string\)](NumberBaseExtensions.ThrowIfNegativeOrZero.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfNegativeOrZero_T_(thisSystem.Nullable_T_,string) 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfNegativeOrZero\\(this System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified value is negative or zero\. | +| [ThrowIfNegativeOrZero<T>\(this T, string\)](NumberBaseExtensions.ThrowIfNegativeOrZero.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfNegativeOrZero_T_(thisT,string) 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfNegativeOrZero\\(this T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified value is negative or zero\. | +| [ThrowIfPositive<T>\(this Nullable<T>, string\)](NumberBaseExtensions.ThrowIfPositive.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfPositive_T_(thisSystem.Nullable_T_,string) 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfPositive\\(this System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified value is positive\. | +| [ThrowIfPositive<T>\(this T, string\)](NumberBaseExtensions.ThrowIfPositive.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfPositive_T_(thisT,string) 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfPositive\\(this T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified value is positive\. | +| [ThrowIfZero<T>\(this Nullable<T>, string\)](NumberBaseExtensions.ThrowIfZero.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfZero_T_(thisSystem.Nullable_T_,string) 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfZero\\(this System\.Nullable\, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified value is zero\. | +| [ThrowIfZero<T>\(this T, string\)](NumberBaseExtensions.ThrowIfZero.md#DevElf.ArgumentValidation.NumberBaseExtensions.ThrowIfZero_T_(thisT,string) 'DevElf\.ArgumentValidation\.NumberBaseExtensions\.ThrowIfZero\\(this T, string\)') | Throws an [System\.ArgumentOutOfRangeException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception 'System\.ArgumentOutOfRangeException') if the specified value is zero\. | diff --git a/docs/api/DevElf/README.md b/docs/api/DevElf/README.md new file mode 100644 index 0000000..c838230 --- /dev/null +++ b/docs/api/DevElf/README.md @@ -0,0 +1,9 @@ +#### [DevElf](README.md 'README') + +## DevElf Assembly + +| Namespaces | | +| :--- | :--- | +| [DevElf](DevElf.md 'DevElf') | | +| [DevElf\.ArgumentValidation](DevElf.ArgumentValidation.md 'DevElf\.ArgumentValidation') | | +| [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions') | | diff --git a/docs/api/DevElf/StringExtensions.IsNotNull.GOG4FDWMXCHP33679EC3INILB.md b/docs/api/DevElf/StringExtensions.IsNotNull.GOG4FDWMXCHP33679EC3INILB.md new file mode 100644 index 0000000..cc33325 --- /dev/null +++ b/docs/api/DevElf/StringExtensions.IsNotNull.GOG4FDWMXCHP33679EC3INILB.md @@ -0,0 +1,23 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[StringExtensions](StringExtensions.md 'DevElf\.Extensions\.StringExtensions') + +## StringExtensions\.IsNotNull\(this string\) Method + +Returns [true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool') when [text](StringExtensions.IsNotNull.GOG4FDWMXCHP33679EC3INILB.md#DevElf.Extensions.StringExtensions.IsNotNull(thisstring).text 'DevElf\.Extensions\.StringExtensions\.IsNotNull\(this string\)\.text') is not +[null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + +```csharp +public static bool IsNotNull(this string? text); +``` +#### Parameters + + + +`text` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The string to check\. + +#### Returns +[System\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean') +[true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool') if [text](StringExtensions.IsNotNull.GOG4FDWMXCHP33679EC3INILB.md#DevElf.Extensions.StringExtensions.IsNotNull(thisstring).text 'DevElf\.Extensions\.StringExtensions\.IsNotNull\(this string\)\.text') is not [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null'); + otherwise, [false](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool')\. \ No newline at end of file diff --git a/docs/api/DevElf/StringExtensions.IsNotNullOrEmpty.KOMZAKBYLVXEEOD08YGARAPM4.md b/docs/api/DevElf/StringExtensions.IsNotNullOrEmpty.KOMZAKBYLVXEEOD08YGARAPM4.md new file mode 100644 index 0000000..b9682bf --- /dev/null +++ b/docs/api/DevElf/StringExtensions.IsNotNullOrEmpty.KOMZAKBYLVXEEOD08YGARAPM4.md @@ -0,0 +1,23 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[StringExtensions](StringExtensions.md 'DevElf\.Extensions\.StringExtensions') + +## StringExtensions\.IsNotNullOrEmpty\(this string\) Method + +Returns [true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool') when [text](StringExtensions.IsNotNullOrEmpty.KOMZAKBYLVXEEOD08YGARAPM4.md#DevElf.Extensions.StringExtensions.IsNotNullOrEmpty(thisstring).text 'DevElf\.Extensions\.StringExtensions\.IsNotNullOrEmpty\(this string\)\.text') is not +[null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null') and not an empty string\. + +```csharp +public static bool IsNotNullOrEmpty(this string? text); +``` +#### Parameters + + + +`text` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The string to check\. + +#### Returns +[System\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean') +[true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool') if [text](StringExtensions.IsNotNullOrEmpty.KOMZAKBYLVXEEOD08YGARAPM4.md#DevElf.Extensions.StringExtensions.IsNotNullOrEmpty(thisstring).text 'DevElf\.Extensions\.StringExtensions\.IsNotNullOrEmpty\(this string\)\.text') is not [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null') + and not empty; otherwise, [false](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool')\. \ No newline at end of file diff --git a/docs/api/DevElf/StringExtensions.IsNotNullOrWhiteSpace.9919O1K4JIH04407ZF15FU221.md b/docs/api/DevElf/StringExtensions.IsNotNullOrWhiteSpace.9919O1K4JIH04407ZF15FU221.md new file mode 100644 index 0000000..bc43802 --- /dev/null +++ b/docs/api/DevElf/StringExtensions.IsNotNullOrWhiteSpace.9919O1K4JIH04407ZF15FU221.md @@ -0,0 +1,24 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[StringExtensions](StringExtensions.md 'DevElf\.Extensions\.StringExtensions') + +## StringExtensions\.IsNotNullOrWhiteSpace\(this string\) Method + +Returns [true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool') when [text](StringExtensions.IsNotNullOrWhiteSpace.9919O1K4JIH04407ZF15FU221.md#DevElf.Extensions.StringExtensions.IsNotNullOrWhiteSpace(thisstring).text 'DevElf\.Extensions\.StringExtensions\.IsNotNullOrWhiteSpace\(this string\)\.text') is not +[null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null') and does not consist only of white\-space characters\. + +```csharp +public static bool IsNotNullOrWhiteSpace(this string? text); +``` +#### Parameters + + + +`text` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The string to check\. + +#### Returns +[System\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean') +[true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool') if [text](StringExtensions.IsNotNullOrWhiteSpace.9919O1K4JIH04407ZF15FU221.md#DevElf.Extensions.StringExtensions.IsNotNullOrWhiteSpace(thisstring).text 'DevElf\.Extensions\.StringExtensions\.IsNotNullOrWhiteSpace\(this string\)\.text') is not [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null') + and does not consist only of white\-space characters; otherwise, + [false](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool')\. \ No newline at end of file diff --git a/docs/api/DevElf/StringExtensions.IsNull.9K7FPD1SVNHTXA9PG00T6WJB7.md b/docs/api/DevElf/StringExtensions.IsNull.9K7FPD1SVNHTXA9PG00T6WJB7.md new file mode 100644 index 0000000..51d6d18 --- /dev/null +++ b/docs/api/DevElf/StringExtensions.IsNull.9K7FPD1SVNHTXA9PG00T6WJB7.md @@ -0,0 +1,22 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[StringExtensions](StringExtensions.md 'DevElf\.Extensions\.StringExtensions') + +## StringExtensions\.IsNull\(this string\) Method + +Returns [true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool') when [text](StringExtensions.IsNull.9K7FPD1SVNHTXA9PG00T6WJB7.md#DevElf.Extensions.StringExtensions.IsNull(thisstring).text 'DevElf\.Extensions\.StringExtensions\.IsNull\(this string\)\.text') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + +```csharp +public static bool IsNull(this string? text); +``` +#### Parameters + + + +`text` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The string to check\. + +#### Returns +[System\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean') +[true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool') if [text](StringExtensions.IsNull.9K7FPD1SVNHTXA9PG00T6WJB7.md#DevElf.Extensions.StringExtensions.IsNull(thisstring).text 'DevElf\.Extensions\.StringExtensions\.IsNull\(this string\)\.text') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null'); + otherwise, [false](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool')\. \ No newline at end of file diff --git a/docs/api/DevElf/StringExtensions.IsNullOrEmpty.83A6J6VCAV38Q1YDNQBEEPYKB.md b/docs/api/DevElf/StringExtensions.IsNullOrEmpty.83A6J6VCAV38Q1YDNQBEEPYKB.md new file mode 100644 index 0000000..dbaf553 --- /dev/null +++ b/docs/api/DevElf/StringExtensions.IsNullOrEmpty.83A6J6VCAV38Q1YDNQBEEPYKB.md @@ -0,0 +1,23 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[StringExtensions](StringExtensions.md 'DevElf\.Extensions\.StringExtensions') + +## StringExtensions\.IsNullOrEmpty\(this string\) Method + +Returns [true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool') when [text](StringExtensions.IsNullOrEmpty.83A6J6VCAV38Q1YDNQBEEPYKB.md#DevElf.Extensions.StringExtensions.IsNullOrEmpty(thisstring).text 'DevElf\.Extensions\.StringExtensions\.IsNullOrEmpty\(this string\)\.text') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null') +or an empty string \(`string.Empty`\)\. + +```csharp +public static bool IsNullOrEmpty(this string? text); +``` +#### Parameters + + + +`text` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The string to check\. + +#### Returns +[System\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean') +[true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool') if [text](StringExtensions.IsNullOrEmpty.83A6J6VCAV38Q1YDNQBEEPYKB.md#DevElf.Extensions.StringExtensions.IsNullOrEmpty(thisstring).text 'DevElf\.Extensions\.StringExtensions\.IsNullOrEmpty\(this string\)\.text') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null') or + empty; otherwise, [false](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool')\. \ No newline at end of file diff --git a/docs/api/DevElf/StringExtensions.IsNullOrWhiteSpace.TPNVX18CCNJW0BW0NI3QBH3X1.md b/docs/api/DevElf/StringExtensions.IsNullOrWhiteSpace.TPNVX18CCNJW0BW0NI3QBH3X1.md new file mode 100644 index 0000000..56fe2cc --- /dev/null +++ b/docs/api/DevElf/StringExtensions.IsNullOrWhiteSpace.TPNVX18CCNJW0BW0NI3QBH3X1.md @@ -0,0 +1,23 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[StringExtensions](StringExtensions.md 'DevElf\.Extensions\.StringExtensions') + +## StringExtensions\.IsNullOrWhiteSpace\(this string\) Method + +Returns [true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool') when [text](StringExtensions.IsNullOrWhiteSpace.TPNVX18CCNJW0BW0NI3QBH3X1.md#DevElf.Extensions.StringExtensions.IsNullOrWhiteSpace(thisstring).text 'DevElf\.Extensions\.StringExtensions\.IsNullOrWhiteSpace\(this string\)\.text') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null') +or consists only of white\-space characters\. + +```csharp +public static bool IsNullOrWhiteSpace(this string? text); +``` +#### Parameters + + + +`text` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The string to check\. + +#### Returns +[System\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean') +[true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool') if [text](StringExtensions.IsNullOrWhiteSpace.TPNVX18CCNJW0BW0NI3QBH3X1.md#DevElf.Extensions.StringExtensions.IsNullOrWhiteSpace(thisstring).text 'DevElf\.Extensions\.StringExtensions\.IsNullOrWhiteSpace\(this string\)\.text') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null') or + consists only of white\-space characters; otherwise, [false](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool')\. \ No newline at end of file diff --git a/docs/api/DevElf/StringExtensions.ThrowIfNullOrEmpty.D8P8RJ38QN1GJYOQY7V7DCNDC.md b/docs/api/DevElf/StringExtensions.ThrowIfNullOrEmpty.D8P8RJ38QN1GJYOQY7V7DCNDC.md new file mode 100644 index 0000000..d5fc90a --- /dev/null +++ b/docs/api/DevElf/StringExtensions.ThrowIfNullOrEmpty.D8P8RJ38QN1GJYOQY7V7DCNDC.md @@ -0,0 +1,31 @@ +#### [DevElf](README.md 'README') +### [DevElf\.ArgumentValidation](DevElf.ArgumentValidation.md 'DevElf\.ArgumentValidation').[StringExtensions](StringExtensions.md 'DevElf\.ArgumentValidation\.StringExtensions') + +## StringExtensions\.ThrowIfNullOrEmpty\(this string, string\) Method + +Throws an [System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') when [argument](StringExtensions.ThrowIfNullOrEmpty.D8P8RJ38QN1GJYOQY7V7DCNDC.md#DevElf.ArgumentValidation.StringExtensions.ThrowIfNullOrEmpty(thisstring,string).argument 'DevElf\.ArgumentValidation\.StringExtensions\.ThrowIfNullOrEmpty\(this string, string\)\.argument') +is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null') or an empty string\. + +```csharp +public static void ThrowIfNullOrEmpty(this string? argument, string parameterName=null); +``` +#### Parameters + + + +`argument` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The string to validate\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the parameter\. This is supplied automatically by the compiler +when the method is used as an extension method because of the +[System\.Runtime\.CompilerServices\.CallerArgumentExpressionAttribute](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.callerargumentexpressionattribute 'System\.Runtime\.CompilerServices\.CallerArgumentExpressionAttribute') on this parameter\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +Thrown when [argument](StringExtensions.ThrowIfNullOrEmpty.D8P8RJ38QN1GJYOQY7V7DCNDC.md#DevElf.ArgumentValidation.StringExtensions.ThrowIfNullOrEmpty(thisstring,string).argument 'DevElf\.ArgumentValidation\.StringExtensions\.ThrowIfNullOrEmpty\(this string, string\)\.argument') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null') or empty\. \ No newline at end of file diff --git a/docs/api/DevElf/StringExtensions.ThrowIfNullOrWhiteSpace.WMBRDAXWAI57LA4GBGL662203.md b/docs/api/DevElf/StringExtensions.ThrowIfNullOrWhiteSpace.WMBRDAXWAI57LA4GBGL662203.md new file mode 100644 index 0000000..9bd61d1 --- /dev/null +++ b/docs/api/DevElf/StringExtensions.ThrowIfNullOrWhiteSpace.WMBRDAXWAI57LA4GBGL662203.md @@ -0,0 +1,35 @@ +#### [DevElf](README.md 'README') +### [DevElf\.ArgumentValidation](DevElf.ArgumentValidation.md 'DevElf\.ArgumentValidation').[StringExtensions](StringExtensions.md 'DevElf\.ArgumentValidation\.StringExtensions') + +## StringExtensions\.ThrowIfNullOrWhiteSpace\(this string, string\) Method + +Throws an [System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') when [argument](StringExtensions.ThrowIfNullOrWhiteSpace.WMBRDAXWAI57LA4GBGL662203.md#DevElf.ArgumentValidation.StringExtensions.ThrowIfNullOrWhiteSpace(thisstring,string).argument 'DevElf\.ArgumentValidation\.StringExtensions\.ThrowIfNullOrWhiteSpace\(this string, string\)\.argument') is +[null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null'), or an [System\.ArgumentException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentexception 'System\.ArgumentException') when it consists only of +white\-space characters\. + +```csharp +public static void ThrowIfNullOrWhiteSpace(this string? argument, string parameterName=null); +``` +#### Parameters + + + +`argument` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The string to validate\. + + + +`parameterName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the parameter\. This is supplied automatically by the compiler +when the method is used as an extension method because of the +[System\.Runtime\.CompilerServices\.CallerArgumentExpressionAttribute](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.callerargumentexpressionattribute 'System\.Runtime\.CompilerServices\.CallerArgumentExpressionAttribute') on this parameter\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +Thrown when [argument](StringExtensions.ThrowIfNullOrWhiteSpace.WMBRDAXWAI57LA4GBGL662203.md#DevElf.ArgumentValidation.StringExtensions.ThrowIfNullOrWhiteSpace(thisstring,string).argument 'DevElf\.ArgumentValidation\.StringExtensions\.ThrowIfNullOrWhiteSpace\(this string, string\)\.argument') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + +[System\.ArgumentException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentexception 'System\.ArgumentException') +Thrown when [argument](StringExtensions.ThrowIfNullOrWhiteSpace.WMBRDAXWAI57LA4GBGL662203.md#DevElf.ArgumentValidation.StringExtensions.ThrowIfNullOrWhiteSpace(thisstring,string).argument 'DevElf\.ArgumentValidation\.StringExtensions\.ThrowIfNullOrWhiteSpace\(this string, string\)\.argument') is only whitespace\. \ No newline at end of file diff --git a/docs/api/DevElf/StringExtensions.md b/docs/api/DevElf/StringExtensions.md new file mode 100644 index 0000000..d8df9ef --- /dev/null +++ b/docs/api/DevElf/StringExtensions.md @@ -0,0 +1,17 @@ +#### [DevElf](README.md 'README') +### [DevElf\.ArgumentValidation](DevElf.ArgumentValidation.md 'DevElf\.ArgumentValidation') + +## StringExtensions Class + +Provides extension helpers for validating [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') arguments\. + +```csharp +public static class StringExtensions +``` + +Inheritance [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') 🡒 StringExtensions + +| Methods | | +| :--- | :--- | +| [ThrowIfNullOrEmpty\(this string, string\)](StringExtensions.ThrowIfNullOrEmpty.D8P8RJ38QN1GJYOQY7V7DCNDC.md 'DevElf\.ArgumentValidation\.StringExtensions\.ThrowIfNullOrEmpty\(this string, string\)') | Throws an [System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') when [argument](StringExtensions.ThrowIfNullOrEmpty.D8P8RJ38QN1GJYOQY7V7DCNDC.md#DevElf.ArgumentValidation.StringExtensions.ThrowIfNullOrEmpty(thisstring,string).argument 'DevElf\.ArgumentValidation\.StringExtensions\.ThrowIfNullOrEmpty\(this string, string\)\.argument') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null') or an empty string\. | +| [ThrowIfNullOrWhiteSpace\(this string, string\)](StringExtensions.ThrowIfNullOrWhiteSpace.WMBRDAXWAI57LA4GBGL662203.md 'DevElf\.ArgumentValidation\.StringExtensions\.ThrowIfNullOrWhiteSpace\(this string, string\)') | Throws an [System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') when [argument](StringExtensions.ThrowIfNullOrWhiteSpace.WMBRDAXWAI57LA4GBGL662203.md#DevElf.ArgumentValidation.StringExtensions.ThrowIfNullOrWhiteSpace(thisstring,string).argument 'DevElf\.ArgumentValidation\.StringExtensions\.ThrowIfNullOrWhiteSpace\(this string, string\)\.argument') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null'), or an [System\.ArgumentException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentexception 'System\.ArgumentException') when it consists only of white\-space characters\. | diff --git a/docs/api/DevElf/TimeProviderExtensions.Freeze.JJKQRV3GO414APBG2SPV9FKV1.md b/docs/api/DevElf/TimeProviderExtensions.Freeze.JJKQRV3GO414APBG2SPV9FKV1.md new file mode 100644 index 0000000..3b204f0 --- /dev/null +++ b/docs/api/DevElf/TimeProviderExtensions.Freeze.JJKQRV3GO414APBG2SPV9FKV1.md @@ -0,0 +1,26 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[TimeProviderExtensions](TimeProviderExtensions.md 'DevElf\.Extensions\.TimeProviderExtensions') + +## TimeProviderExtensions\.Freeze\(this TimeProvider\) Method + +Returns a [FrozenTimeProvider](FrozenTimeProvider.md 'DevElf\.FrozenTimeProvider') that is frozen to the current instant of [timeProvider](TimeProviderExtensions.Freeze.JJKQRV3GO414APBG2SPV9FKV1.md#DevElf.Extensions.TimeProviderExtensions.Freeze(thisSystem.TimeProvider).timeProvider 'DevElf\.Extensions\.TimeProviderExtensions\.Freeze\(this System\.TimeProvider\)\.timeProvider')\. + +```csharp +public static System.TimeProvider Freeze(this System.TimeProvider timeProvider); +``` +#### Parameters + + + +`timeProvider` [System\.TimeProvider](https://learn.microsoft.com/en-us/dotnet/api/system.timeprovider 'System\.TimeProvider') + +The source time provider\. + +#### Returns +[System\.TimeProvider](https://learn.microsoft.com/en-us/dotnet/api/system.timeprovider 'System\.TimeProvider') +A frozen time provider\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +If [timeProvider](TimeProviderExtensions.Freeze.JJKQRV3GO414APBG2SPV9FKV1.md#DevElf.Extensions.TimeProviderExtensions.Freeze(thisSystem.TimeProvider).timeProvider 'DevElf\.Extensions\.TimeProviderExtensions\.Freeze\(this System\.TimeProvider\)\.timeProvider') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. \ No newline at end of file diff --git a/docs/api/DevElf/TimeProviderExtensions.GetLocalNowAsDateTime.M84J6LMDXEKC4KGHO8DWP8HO4.md b/docs/api/DevElf/TimeProviderExtensions.GetLocalNowAsDateTime.M84J6LMDXEKC4KGHO8DWP8HO4.md new file mode 100644 index 0000000..79ebf3a --- /dev/null +++ b/docs/api/DevElf/TimeProviderExtensions.GetLocalNowAsDateTime.M84J6LMDXEKC4KGHO8DWP8HO4.md @@ -0,0 +1,26 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[TimeProviderExtensions](TimeProviderExtensions.md 'DevElf\.Extensions\.TimeProviderExtensions') + +## TimeProviderExtensions\.GetLocalNowAsDateTime\(this TimeProvider\) Method + +Returns the current local time from the provider as a [System\.DateTime](https://learn.microsoft.com/en-us/dotnet/api/system.datetime 'System\.DateTime')\. + +```csharp +public static System.DateTime GetLocalNowAsDateTime(this System.TimeProvider timeProvider); +``` +#### Parameters + + + +`timeProvider` [System\.TimeProvider](https://learn.microsoft.com/en-us/dotnet/api/system.timeprovider 'System\.TimeProvider') + +The source time provider\. + +#### Returns +[System\.DateTime](https://learn.microsoft.com/en-us/dotnet/api/system.datetime 'System\.DateTime') +The current local [System\.DateTime](https://learn.microsoft.com/en-us/dotnet/api/system.datetime 'System\.DateTime')\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +If [timeProvider](TimeProviderExtensions.GetLocalNowAsDateTime.M84J6LMDXEKC4KGHO8DWP8HO4.md#DevElf.Extensions.TimeProviderExtensions.GetLocalNowAsDateTime(thisSystem.TimeProvider).timeProvider 'DevElf\.Extensions\.TimeProviderExtensions\.GetLocalNowAsDateTime\(this System\.TimeProvider\)\.timeProvider') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. \ No newline at end of file diff --git a/docs/api/DevElf/TimeProviderExtensions.GetTimeOfDay.BZQPKC1HDAVIWAAQUAOFRTGA1.md b/docs/api/DevElf/TimeProviderExtensions.GetTimeOfDay.BZQPKC1HDAVIWAAQUAOFRTGA1.md new file mode 100644 index 0000000..245941b --- /dev/null +++ b/docs/api/DevElf/TimeProviderExtensions.GetTimeOfDay.BZQPKC1HDAVIWAAQUAOFRTGA1.md @@ -0,0 +1,26 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[TimeProviderExtensions](TimeProviderExtensions.md 'DevElf\.Extensions\.TimeProviderExtensions') + +## TimeProviderExtensions\.GetTimeOfDay\(this TimeProvider\) Method + +Returns the current local time\-of\-day from the provider as a [System\.TimeOnly](https://learn.microsoft.com/en-us/dotnet/api/system.timeonly 'System\.TimeOnly')\. + +```csharp +public static System.TimeOnly GetTimeOfDay(this System.TimeProvider timeProvider); +``` +#### Parameters + + + +`timeProvider` [System\.TimeProvider](https://learn.microsoft.com/en-us/dotnet/api/system.timeprovider 'System\.TimeProvider') + +The source time provider\. + +#### Returns +[System\.TimeOnly](https://learn.microsoft.com/en-us/dotnet/api/system.timeonly 'System\.TimeOnly') +The current local [System\.TimeOnly](https://learn.microsoft.com/en-us/dotnet/api/system.timeonly 'System\.TimeOnly')\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +If [timeProvider](TimeProviderExtensions.GetTimeOfDay.BZQPKC1HDAVIWAAQUAOFRTGA1.md#DevElf.Extensions.TimeProviderExtensions.GetTimeOfDay(thisSystem.TimeProvider).timeProvider 'DevElf\.Extensions\.TimeProviderExtensions\.GetTimeOfDay\(this System\.TimeProvider\)\.timeProvider') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. \ No newline at end of file diff --git a/docs/api/DevElf/TimeProviderExtensions.GetToday.ZV4BS2Q217E0OPUMVKLSXRLHE.md b/docs/api/DevElf/TimeProviderExtensions.GetToday.ZV4BS2Q217E0OPUMVKLSXRLHE.md new file mode 100644 index 0000000..f16f168 --- /dev/null +++ b/docs/api/DevElf/TimeProviderExtensions.GetToday.ZV4BS2Q217E0OPUMVKLSXRLHE.md @@ -0,0 +1,26 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[TimeProviderExtensions](TimeProviderExtensions.md 'DevElf\.Extensions\.TimeProviderExtensions') + +## TimeProviderExtensions\.GetToday\(this TimeProvider\) Method + +Returns the current local date from the provider as a [System\.DateOnly](https://learn.microsoft.com/en-us/dotnet/api/system.dateonly 'System\.DateOnly')\. + +```csharp +public static System.DateOnly GetToday(this System.TimeProvider timeProvider); +``` +#### Parameters + + + +`timeProvider` [System\.TimeProvider](https://learn.microsoft.com/en-us/dotnet/api/system.timeprovider 'System\.TimeProvider') + +The source time provider\. + +#### Returns +[System\.DateOnly](https://learn.microsoft.com/en-us/dotnet/api/system.dateonly 'System\.DateOnly') +The current local [System\.DateOnly](https://learn.microsoft.com/en-us/dotnet/api/system.dateonly 'System\.DateOnly')\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +If [timeProvider](TimeProviderExtensions.GetToday.ZV4BS2Q217E0OPUMVKLSXRLHE.md#DevElf.Extensions.TimeProviderExtensions.GetToday(thisSystem.TimeProvider).timeProvider 'DevElf\.Extensions\.TimeProviderExtensions\.GetToday\(this System\.TimeProvider\)\.timeProvider') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. \ No newline at end of file diff --git a/docs/api/DevElf/TimeProviderExtensions.GetUtcNowAsDateTime.G3U2UI7C7M6TWL6JEY3ZC6PX3.md b/docs/api/DevElf/TimeProviderExtensions.GetUtcNowAsDateTime.G3U2UI7C7M6TWL6JEY3ZC6PX3.md new file mode 100644 index 0000000..1b2169a --- /dev/null +++ b/docs/api/DevElf/TimeProviderExtensions.GetUtcNowAsDateTime.G3U2UI7C7M6TWL6JEY3ZC6PX3.md @@ -0,0 +1,26 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[TimeProviderExtensions](TimeProviderExtensions.md 'DevElf\.Extensions\.TimeProviderExtensions') + +## TimeProviderExtensions\.GetUtcNowAsDateTime\(this TimeProvider\) Method + +Returns the current UTC time from the provider as a [System\.DateTime](https://learn.microsoft.com/en-us/dotnet/api/system.datetime 'System\.DateTime')\. + +```csharp +public static System.DateTime GetUtcNowAsDateTime(this System.TimeProvider timeProvider); +``` +#### Parameters + + + +`timeProvider` [System\.TimeProvider](https://learn.microsoft.com/en-us/dotnet/api/system.timeprovider 'System\.TimeProvider') + +The source time provider\. + +#### Returns +[System\.DateTime](https://learn.microsoft.com/en-us/dotnet/api/system.datetime 'System\.DateTime') +The current UTC [System\.DateTime](https://learn.microsoft.com/en-us/dotnet/api/system.datetime 'System\.DateTime')\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +If [timeProvider](TimeProviderExtensions.GetUtcNowAsDateTime.G3U2UI7C7M6TWL6JEY3ZC6PX3.md#DevElf.Extensions.TimeProviderExtensions.GetUtcNowAsDateTime(thisSystem.TimeProvider).timeProvider 'DevElf\.Extensions\.TimeProviderExtensions\.GetUtcNowAsDateTime\(this System\.TimeProvider\)\.timeProvider') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. \ No newline at end of file diff --git a/docs/api/DevElf/TimeProviderExtensions.GetUtcTimeOfDay.BGDOQDAMLTGGQQS14AWAESZF6.md b/docs/api/DevElf/TimeProviderExtensions.GetUtcTimeOfDay.BGDOQDAMLTGGQQS14AWAESZF6.md new file mode 100644 index 0000000..aeb619d --- /dev/null +++ b/docs/api/DevElf/TimeProviderExtensions.GetUtcTimeOfDay.BGDOQDAMLTGGQQS14AWAESZF6.md @@ -0,0 +1,26 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[TimeProviderExtensions](TimeProviderExtensions.md 'DevElf\.Extensions\.TimeProviderExtensions') + +## TimeProviderExtensions\.GetUtcTimeOfDay\(this TimeProvider\) Method + +Returns the current UTC time\-of\-day from the provider as a [System\.TimeOnly](https://learn.microsoft.com/en-us/dotnet/api/system.timeonly 'System\.TimeOnly')\. + +```csharp +public static System.TimeOnly GetUtcTimeOfDay(this System.TimeProvider timeProvider); +``` +#### Parameters + + + +`timeProvider` [System\.TimeProvider](https://learn.microsoft.com/en-us/dotnet/api/system.timeprovider 'System\.TimeProvider') + +The source time provider\. + +#### Returns +[System\.TimeOnly](https://learn.microsoft.com/en-us/dotnet/api/system.timeonly 'System\.TimeOnly') +The current UTC [System\.TimeOnly](https://learn.microsoft.com/en-us/dotnet/api/system.timeonly 'System\.TimeOnly')\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +If [timeProvider](TimeProviderExtensions.GetUtcTimeOfDay.BGDOQDAMLTGGQQS14AWAESZF6.md#DevElf.Extensions.TimeProviderExtensions.GetUtcTimeOfDay(thisSystem.TimeProvider).timeProvider 'DevElf\.Extensions\.TimeProviderExtensions\.GetUtcTimeOfDay\(this System\.TimeProvider\)\.timeProvider') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. \ No newline at end of file diff --git a/docs/api/DevElf/TimeProviderExtensions.GetUtcToday.8SIFE92OI2ICNT916X4QAWNY7.md b/docs/api/DevElf/TimeProviderExtensions.GetUtcToday.8SIFE92OI2ICNT916X4QAWNY7.md new file mode 100644 index 0000000..9a45f61 --- /dev/null +++ b/docs/api/DevElf/TimeProviderExtensions.GetUtcToday.8SIFE92OI2ICNT916X4QAWNY7.md @@ -0,0 +1,26 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[TimeProviderExtensions](TimeProviderExtensions.md 'DevElf\.Extensions\.TimeProviderExtensions') + +## TimeProviderExtensions\.GetUtcToday\(this TimeProvider\) Method + +Returns the current UTC date from the provider as a [System\.DateOnly](https://learn.microsoft.com/en-us/dotnet/api/system.dateonly 'System\.DateOnly')\. + +```csharp +public static System.DateOnly GetUtcToday(this System.TimeProvider timeProvider); +``` +#### Parameters + + + +`timeProvider` [System\.TimeProvider](https://learn.microsoft.com/en-us/dotnet/api/system.timeprovider 'System\.TimeProvider') + +The source time provider\. + +#### Returns +[System\.DateOnly](https://learn.microsoft.com/en-us/dotnet/api/system.dateonly 'System\.DateOnly') +The current UTC [System\.DateOnly](https://learn.microsoft.com/en-us/dotnet/api/system.dateonly 'System\.DateOnly')\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +If [timeProvider](TimeProviderExtensions.GetUtcToday.8SIFE92OI2ICNT916X4QAWNY7.md#DevElf.Extensions.TimeProviderExtensions.GetUtcToday(thisSystem.TimeProvider).timeProvider 'DevElf\.Extensions\.TimeProviderExtensions\.GetUtcToday\(this System\.TimeProvider\)\.timeProvider') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. \ No newline at end of file diff --git a/docs/api/DevElf/TimeProviderExtensions.md b/docs/api/DevElf/TimeProviderExtensions.md new file mode 100644 index 0000000..e5808fd --- /dev/null +++ b/docs/api/DevElf/TimeProviderExtensions.md @@ -0,0 +1,22 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions') + +## TimeProviderExtensions Class + +Extension methods for [System\.TimeProvider](https://learn.microsoft.com/en-us/dotnet/api/system.timeprovider 'System\.TimeProvider') to provide convenient conversions and helpers\. + +```csharp +public static class TimeProviderExtensions +``` + +Inheritance [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') 🡒 TimeProviderExtensions + +| Methods | | +| :--- | :--- | +| [Freeze\(this TimeProvider\)](TimeProviderExtensions.Freeze.JJKQRV3GO414APBG2SPV9FKV1.md 'DevElf\.Extensions\.TimeProviderExtensions\.Freeze\(this System\.TimeProvider\)') | Returns a [FrozenTimeProvider](FrozenTimeProvider.md 'DevElf\.FrozenTimeProvider') that is frozen to the current instant of [timeProvider](TimeProviderExtensions.Freeze.JJKQRV3GO414APBG2SPV9FKV1.md#DevElf.Extensions.TimeProviderExtensions.Freeze(thisSystem.TimeProvider).timeProvider 'DevElf\.Extensions\.TimeProviderExtensions\.Freeze\(this System\.TimeProvider\)\.timeProvider')\. | +| [GetLocalNowAsDateTime\(this TimeProvider\)](TimeProviderExtensions.GetLocalNowAsDateTime.M84J6LMDXEKC4KGHO8DWP8HO4.md 'DevElf\.Extensions\.TimeProviderExtensions\.GetLocalNowAsDateTime\(this System\.TimeProvider\)') | Returns the current local time from the provider as a [System\.DateTime](https://learn.microsoft.com/en-us/dotnet/api/system.datetime 'System\.DateTime')\. | +| [GetTimeOfDay\(this TimeProvider\)](TimeProviderExtensions.GetTimeOfDay.BZQPKC1HDAVIWAAQUAOFRTGA1.md 'DevElf\.Extensions\.TimeProviderExtensions\.GetTimeOfDay\(this System\.TimeProvider\)') | Returns the current local time\-of\-day from the provider as a [System\.TimeOnly](https://learn.microsoft.com/en-us/dotnet/api/system.timeonly 'System\.TimeOnly')\. | +| [GetToday\(this TimeProvider\)](TimeProviderExtensions.GetToday.ZV4BS2Q217E0OPUMVKLSXRLHE.md 'DevElf\.Extensions\.TimeProviderExtensions\.GetToday\(this System\.TimeProvider\)') | Returns the current local date from the provider as a [System\.DateOnly](https://learn.microsoft.com/en-us/dotnet/api/system.dateonly 'System\.DateOnly')\. | +| [GetUtcNowAsDateTime\(this TimeProvider\)](TimeProviderExtensions.GetUtcNowAsDateTime.G3U2UI7C7M6TWL6JEY3ZC6PX3.md 'DevElf\.Extensions\.TimeProviderExtensions\.GetUtcNowAsDateTime\(this System\.TimeProvider\)') | Returns the current UTC time from the provider as a [System\.DateTime](https://learn.microsoft.com/en-us/dotnet/api/system.datetime 'System\.DateTime')\. | +| [GetUtcTimeOfDay\(this TimeProvider\)](TimeProviderExtensions.GetUtcTimeOfDay.BGDOQDAMLTGGQQS14AWAESZF6.md 'DevElf\.Extensions\.TimeProviderExtensions\.GetUtcTimeOfDay\(this System\.TimeProvider\)') | Returns the current UTC time\-of\-day from the provider as a [System\.TimeOnly](https://learn.microsoft.com/en-us/dotnet/api/system.timeonly 'System\.TimeOnly')\. | +| [GetUtcToday\(this TimeProvider\)](TimeProviderExtensions.GetUtcToday.8SIFE92OI2ICNT916X4QAWNY7.md 'DevElf\.Extensions\.TimeProviderExtensions\.GetUtcToday\(this System\.TimeProvider\)') | Returns the current UTC date from the provider as a [System\.DateOnly](https://learn.microsoft.com/en-us/dotnet/api/system.dateonly 'System\.DateOnly')\. | diff --git a/docs/api/DevElf/TypeExtensions.GetCustomFormattedTypeFullName.P76O9STWHPAGRI25QVIUQ5MVD.md b/docs/api/DevElf/TypeExtensions.GetCustomFormattedTypeFullName.P76O9STWHPAGRI25QVIUQ5MVD.md new file mode 100644 index 0000000..eddc521 --- /dev/null +++ b/docs/api/DevElf/TypeExtensions.GetCustomFormattedTypeFullName.P76O9STWHPAGRI25QVIUQ5MVD.md @@ -0,0 +1,35 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[TypeExtensions](TypeExtensions.md 'DevElf\.Extensions\.TypeExtensions') + +## TypeExtensions\.GetCustomFormattedTypeFullName\(this Type, string, string\) Method + +Gets a formatted full name for the type using a custom format string\. + +```csharp +public static string GetCustomFormattedTypeFullName(this System.Type type, string format, string argumentSeparator=", "); +``` +#### Parameters + + + +`type` [System\.Type](https://learn.microsoft.com/en-us/dotnet/api/system.type 'System\.Type') + +The type to format\. + + + +`format` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The format string where \{0\} is the base type full name and \{1\} is the generic +arguments\. For non\-generic types, only \{0\} is used\. + + + +`argumentSeparator` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The string used to separate generic type arguments\. Default is ", "\. + +#### Returns +[System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') +A formatted string representation of the type full name\. For non\-generic types, +returns the full type name\. \ No newline at end of file diff --git a/docs/api/DevElf/TypeExtensions.GetCustomFormattedTypeName.IAF1XPCUI7NL3R5U5999O4SM4.md b/docs/api/DevElf/TypeExtensions.GetCustomFormattedTypeName.IAF1XPCUI7NL3R5U5999O4SM4.md new file mode 100644 index 0000000..304a630 --- /dev/null +++ b/docs/api/DevElf/TypeExtensions.GetCustomFormattedTypeName.IAF1XPCUI7NL3R5U5999O4SM4.md @@ -0,0 +1,42 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[TypeExtensions](TypeExtensions.md 'DevElf\.Extensions\.TypeExtensions') + +## TypeExtensions\.GetCustomFormattedTypeName\(this Type, string, string, bool\) Method + +Gets a formatted name for the type using a custom format string\. + +```csharp +public static string GetCustomFormattedTypeName(this System.Type type, string format, string argumentSeparator=", ", bool useBuiltInTypeNameAliases=false); +``` +#### Parameters + + + +`type` [System\.Type](https://learn.microsoft.com/en-us/dotnet/api/system.type 'System\.Type') + +The type to format\. + + + +`format` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The format string where \{0\} is the base type name and \{1\} is the generic arguments\. +For non\-generic types, only \{0\} is used\. + + + +`argumentSeparator` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The string used to separate generic type arguments\. Default is ", "\. + + + +`useBuiltInTypeNameAliases` [System\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean') + +[true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool') to use C\# keyword aliases for built\-in types; + otherwise, [false](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool')\. + +#### Returns +[System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') +A formatted string representation of the type name\. For non\-generic types, returns +the simple type name\. \ No newline at end of file diff --git a/docs/api/DevElf/TypeExtensions.GetFriendlyTypeFullName.TGDWG5RWDUJW2KUFF1GSUH52B.md b/docs/api/DevElf/TypeExtensions.GetFriendlyTypeFullName.TGDWG5RWDUJW2KUFF1GSUH52B.md new file mode 100644 index 0000000..316d236 --- /dev/null +++ b/docs/api/DevElf/TypeExtensions.GetFriendlyTypeFullName.TGDWG5RWDUJW2KUFF1GSUH52B.md @@ -0,0 +1,24 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[TypeExtensions](TypeExtensions.md 'DevElf\.Extensions\.TypeExtensions') + +## TypeExtensions\.GetFriendlyTypeFullName\(this Type\) Method + +Gets a friendly, readable full name for the type using angle bracket notation for +generic types\. + +```csharp +public static string GetFriendlyTypeFullName(this System.Type type); +``` +#### Parameters + + + +`type` [System\.Type](https://learn.microsoft.com/en-us/dotnet/api/system.type 'System\.Type') + +The type to format\. + +#### Returns +[System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') +A string representing the type full name\. For generic types, returns the format +"Namespace\.TypeName\"\. For non\-generic types, returns the full type +name\. \ No newline at end of file diff --git a/docs/api/DevElf/TypeExtensions.GetFriendlyTypeName.J35G2Y7DEMNMKUW3HYFEJQRE4.md b/docs/api/DevElf/TypeExtensions.GetFriendlyTypeName.J35G2Y7DEMNMKUW3HYFEJQRE4.md new file mode 100644 index 0000000..96ae3a5 --- /dev/null +++ b/docs/api/DevElf/TypeExtensions.GetFriendlyTypeName.J35G2Y7DEMNMKUW3HYFEJQRE4.md @@ -0,0 +1,30 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[TypeExtensions](TypeExtensions.md 'DevElf\.Extensions\.TypeExtensions') + +## TypeExtensions\.GetFriendlyTypeName\(this Type, bool\) Method + +Gets a friendly, readable name for the type using angle bracket notation for generic +types\. + +```csharp +public static string GetFriendlyTypeName(this System.Type type, bool useBuiltInTypeNameAliases=false); +``` +#### Parameters + + + +`type` [System\.Type](https://learn.microsoft.com/en-us/dotnet/api/system.type 'System\.Type') + +The type to format\. + + + +`useBuiltInTypeNameAliases` [System\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean') + +[true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool') to use C\# keyword aliases for built\-in types; + otherwise, [false](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool')\. + +#### Returns +[System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') +A string representing the type name\. For generic types, returns the format +"TypeName\"\. For non\-generic types, returns the simple type name\. \ No newline at end of file diff --git a/docs/api/DevElf/TypeExtensions.GetNameWithoutGenericParameters.W1YHOUP03743XOTR3ULZTUPA6.md b/docs/api/DevElf/TypeExtensions.GetNameWithoutGenericParameters.W1YHOUP03743XOTR3ULZTUPA6.md new file mode 100644 index 0000000..ad162d2 --- /dev/null +++ b/docs/api/DevElf/TypeExtensions.GetNameWithoutGenericParameters.W1YHOUP03743XOTR3ULZTUPA6.md @@ -0,0 +1,22 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[TypeExtensions](TypeExtensions.md 'DevElf\.Extensions\.TypeExtensions') + +## TypeExtensions\.GetNameWithoutGenericParameters\(this Type\) Method + +Gets the name of the type without generic parameter indicators\. + +```csharp +public static string GetNameWithoutGenericParameters(this System.Type type); +``` +#### Parameters + + + +`type` [System\.Type](https://learn.microsoft.com/en-us/dotnet/api/system.type 'System\.Type') + +The type to get the name from\. + +#### Returns +[System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') +The type name without the generic parameter count indicator \(e\.g\., "List" instead +of "List\`1"\)\. \ No newline at end of file diff --git a/docs/api/DevElf/TypeExtensions.GetTypeName.UH859SB3JKYGI29AZPHHWSOT5.md b/docs/api/DevElf/TypeExtensions.GetTypeName.UH859SB3JKYGI29AZPHHWSOT5.md new file mode 100644 index 0000000..c4b203a --- /dev/null +++ b/docs/api/DevElf/TypeExtensions.GetTypeName.UH859SB3JKYGI29AZPHHWSOT5.md @@ -0,0 +1,28 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[TypeExtensions](TypeExtensions.md 'DevElf\.Extensions\.TypeExtensions') + +## TypeExtensions\.GetTypeName\(this Type, bool\) Method + +Gets the name of the type, optionally using C\# keyword aliases for built\-in types\. + +```csharp +public static string GetTypeName(this System.Type type, bool useBuiltInTypeNameAliases=false); +``` +#### Parameters + + + +`type` [System\.Type](https://learn.microsoft.com/en-us/dotnet/api/system.type 'System\.Type') + +The type to get the name from\. + + + +`useBuiltInTypeNameAliases` [System\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean') + +[true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool') to use C\# keyword aliases for built\-in types; + otherwise, [false](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool')\. + +#### Returns +[System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') +The name of the type\. \ No newline at end of file diff --git a/docs/api/DevElf/TypeExtensions.IsIEnumerableOfT.94FI3DNSKIQR77KQEYY3O9VJ6.md b/docs/api/DevElf/TypeExtensions.IsIEnumerableOfT.94FI3DNSKIQR77KQEYY3O9VJ6.md new file mode 100644 index 0000000..7c827b4 --- /dev/null +++ b/docs/api/DevElf/TypeExtensions.IsIEnumerableOfT.94FI3DNSKIQR77KQEYY3O9VJ6.md @@ -0,0 +1,30 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[TypeExtensions](TypeExtensions.md 'DevElf\.Extensions\.TypeExtensions') + +## TypeExtensions\.IsIEnumerableOfT\(this Type, bool\) Method + +Determines whether the specified type implements +[System\.Collections\.Generic\.IEnumerable<>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 'System\.Collections\.Generic\.IEnumerable\`1')\. + +```csharp +public static bool IsIEnumerableOfT(this System.Type type, bool excludeString=false); +``` +#### Parameters + + + +`type` [System\.Type](https://learn.microsoft.com/en-us/dotnet/api/system.type 'System\.Type') + +The type to check\. + + + +`excludeString` [System\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean') + +[true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool') to exclude [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') from being considered as + [System\.Collections\.Generic\.IEnumerable<>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 'System\.Collections\.Generic\.IEnumerable\`1'); otherwise, [false](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool')\. + +#### Returns +[System\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean') +[true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool') if the type implements [System\.Collections\.Generic\.IEnumerable<>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 'System\.Collections\.Generic\.IEnumerable\`1'); + otherwise, [false](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool')\. \ No newline at end of file diff --git a/docs/api/DevElf/TypeExtensions.IsStatic.3K24BJS6E9QC8MFS6MLNUI3FA.md b/docs/api/DevElf/TypeExtensions.IsStatic.3K24BJS6E9QC8MFS6MLNUI3FA.md new file mode 100644 index 0000000..26a4b96 --- /dev/null +++ b/docs/api/DevElf/TypeExtensions.IsStatic.3K24BJS6E9QC8MFS6MLNUI3FA.md @@ -0,0 +1,22 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[TypeExtensions](TypeExtensions.md 'DevElf\.Extensions\.TypeExtensions') + +## TypeExtensions\.IsStatic\(this Type\) Method + +Determines whether the specified type is a static class\. + +```csharp +public static bool IsStatic(this System.Type type); +``` +#### Parameters + + + +`type` [System\.Type](https://learn.microsoft.com/en-us/dotnet/api/system.type 'System\.Type') + +The type to check\. + +#### Returns +[System\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean') +[true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool') if the type is a static class; otherwise, + [false](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool')\. \ No newline at end of file diff --git a/docs/api/DevElf/TypeExtensions.TryGetIEnumerableOfTType.0M5ESH17YJABIKN8X3RLK96BC.md b/docs/api/DevElf/TypeExtensions.TryGetIEnumerableOfTType.0M5ESH17YJABIKN8X3RLK96BC.md new file mode 100644 index 0000000..24e3e9e --- /dev/null +++ b/docs/api/DevElf/TypeExtensions.TryGetIEnumerableOfTType.0M5ESH17YJABIKN8X3RLK96BC.md @@ -0,0 +1,37 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[TypeExtensions](TypeExtensions.md 'DevElf\.Extensions\.TypeExtensions') + +## TypeExtensions\.TryGetIEnumerableOfTType\(this Type, Type, bool\) Method + +Attempts to get the [System\.Collections\.Generic\.IEnumerable<>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 'System\.Collections\.Generic\.IEnumerable\`1') interface type from a type that +implements it\. + +```csharp +public static bool TryGetIEnumerableOfTType(this System.Type type, out System.Type? enumerableInterfaceType, bool excludeString=false); +``` +#### Parameters + + + +`type` [System\.Type](https://learn.microsoft.com/en-us/dotnet/api/system.type 'System\.Type') + +The type to check\. + + + +`enumerableInterfaceType` [System\.Type](https://learn.microsoft.com/en-us/dotnet/api/system.type 'System\.Type') + +When this method returns, contains the [System\.Collections\.Generic\.IEnumerable<>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 'System\.Collections\.Generic\.IEnumerable\`1') interface +type if the type implements it; otherwise, [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + + + +`excludeString` [System\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean') + +[true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool') to exclude [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') from being considered as + [System\.Collections\.Generic\.IEnumerable<>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 'System\.Collections\.Generic\.IEnumerable\`1'); otherwise, [false](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool')\. + +#### Returns +[System\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean') +[true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool') if the type implements [System\.Collections\.Generic\.IEnumerable<>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 'System\.Collections\.Generic\.IEnumerable\`1'); + otherwise, [false](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool')\. \ No newline at end of file diff --git a/docs/api/DevElf/TypeExtensions.TryGetTypeOfTFromIEnumerableOfT.W0NGC76YSUAP62VXD2CX03CT1.md b/docs/api/DevElf/TypeExtensions.TryGetTypeOfTFromIEnumerableOfT.W0NGC76YSUAP62VXD2CX03CT1.md new file mode 100644 index 0000000..863c2fc --- /dev/null +++ b/docs/api/DevElf/TypeExtensions.TryGetTypeOfTFromIEnumerableOfT.W0NGC76YSUAP62VXD2CX03CT1.md @@ -0,0 +1,37 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[TypeExtensions](TypeExtensions.md 'DevElf\.Extensions\.TypeExtensions') + +## TypeExtensions\.TryGetTypeOfTFromIEnumerableOfT\(this Type, Type, bool\) Method + +Attempts to get the element type T from a type that implements +[System\.Collections\.Generic\.IEnumerable<>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 'System\.Collections\.Generic\.IEnumerable\`1')\. + +```csharp +public static bool TryGetTypeOfTFromIEnumerableOfT(this System.Type type, out System.Type? typeOfT, bool excludeString=false); +``` +#### Parameters + + + +`type` [System\.Type](https://learn.microsoft.com/en-us/dotnet/api/system.type 'System\.Type') + +The type to check\. + + + +`typeOfT` [System\.Type](https://learn.microsoft.com/en-us/dotnet/api/system.type 'System\.Type') + +When this method returns, contains the element type T if the type implements +[System\.Collections\.Generic\.IEnumerable<>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 'System\.Collections\.Generic\.IEnumerable\`1'); otherwise, [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + + + +`excludeString` [System\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean') + +[true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool') to exclude [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') from being considered as + [System\.Collections\.Generic\.IEnumerable<>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 'System\.Collections\.Generic\.IEnumerable\`1'); otherwise, [false](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool')\. + +#### Returns +[System\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean') +[true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool') if the type implements [System\.Collections\.Generic\.IEnumerable<>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 'System\.Collections\.Generic\.IEnumerable\`1') and + the element type was retrieved; otherwise, [false](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool')\. \ No newline at end of file diff --git a/docs/api/DevElf/TypeExtensions._G_$6B6159A298CA62A8C577E514BE40E3DD.BuiltInTypeAliasMap.md b/docs/api/DevElf/TypeExtensions._G_$6B6159A298CA62A8C577E514BE40E3DD.BuiltInTypeAliasMap.md new file mode 100644 index 0000000..455c18f --- /dev/null +++ b/docs/api/DevElf/TypeExtensions._G_$6B6159A298CA62A8C577E514BE40E3DD.BuiltInTypeAliasMap.md @@ -0,0 +1,13 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[TypeExtensions](TypeExtensions.md 'DevElf\.Extensions\.TypeExtensions').[<G>$6B6159A298CA62A8C577E514BE40E3DD](TypeExtensions._G_$6B6159A298CA62A8C577E514BE40E3DD.md 'DevElf\.Extensions\.TypeExtensions\.\$6B6159A298CA62A8C577E514BE40E3DD') + +## TypeExtensions\.\$6B6159A298CA62A8C577E514BE40E3DD\.BuiltInTypeAliasMap Property + +Gets the dictionary mapping built\-in types to their C\# keyword aliases\. + +```csharp +public static System.Collections.Generic.IReadOnlyDictionary BuiltInTypeAliasMap { get; } +``` + +#### Property Value +[System\.Collections\.Generic\.IReadOnlyDictionary<](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ireadonlydictionary-2 'System\.Collections\.Generic\.IReadOnlyDictionary\`2')[System\.Type](https://learn.microsoft.com/en-us/dotnet/api/system.type 'System\.Type')[,](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ireadonlydictionary-2 'System\.Collections\.Generic\.IReadOnlyDictionary\`2')[System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String')[>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ireadonlydictionary-2 'System\.Collections\.Generic\.IReadOnlyDictionary\`2') \ No newline at end of file diff --git a/docs/api/DevElf/TypeExtensions._G_$6B6159A298CA62A8C577E514BE40E3DD.md b/docs/api/DevElf/TypeExtensions._G_$6B6159A298CA62A8C577E514BE40E3DD.md new file mode 100644 index 0000000..1c55c9a --- /dev/null +++ b/docs/api/DevElf/TypeExtensions._G_$6B6159A298CA62A8C577E514BE40E3DD.md @@ -0,0 +1,14 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[TypeExtensions](TypeExtensions.md 'DevElf\.Extensions\.TypeExtensions') + +## TypeExtensions\.\$6B6159A298CA62A8C577E514BE40E3DD Class + +```csharp +public sealed class TypeExtensions.$6B6159A298CA62A8C577E514BE40E3DD +``` + +Inheritance [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') 🡒 \$6B6159A298CA62A8C577E514BE40E3DD + +| Properties | | +| :--- | :--- | +| [BuiltInTypeAliasMap](TypeExtensions._G_$6B6159A298CA62A8C577E514BE40E3DD.BuiltInTypeAliasMap.md 'DevElf\.Extensions\.TypeExtensions\.\$6B6159A298CA62A8C577E514BE40E3DD\.BuiltInTypeAliasMap') | Gets the dictionary mapping built\-in types to their C\# keyword aliases\. | diff --git a/docs/api/DevElf/TypeExtensions.get_BuiltInTypeAliasMap().md b/docs/api/DevElf/TypeExtensions.get_BuiltInTypeAliasMap().md new file mode 100644 index 0000000..9687a0f --- /dev/null +++ b/docs/api/DevElf/TypeExtensions.get_BuiltInTypeAliasMap().md @@ -0,0 +1,13 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions').[TypeExtensions](TypeExtensions.md 'DevElf\.Extensions\.TypeExtensions') + +## TypeExtensions\.get\_BuiltInTypeAliasMap\(\) Method + +Gets the dictionary mapping built\-in types to their C\# keyword aliases\. + +```csharp +public static System.Collections.Generic.IReadOnlyDictionary get_BuiltInTypeAliasMap(); +``` + +#### Returns +[System\.Collections\.Generic\.IReadOnlyDictionary<](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ireadonlydictionary-2 'System\.Collections\.Generic\.IReadOnlyDictionary\`2')[System\.Type](https://learn.microsoft.com/en-us/dotnet/api/system.type 'System\.Type')[,](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ireadonlydictionary-2 'System\.Collections\.Generic\.IReadOnlyDictionary\`2')[System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String')[>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ireadonlydictionary-2 'System\.Collections\.Generic\.IReadOnlyDictionary\`2') \ No newline at end of file diff --git a/docs/api/DevElf/TypeExtensions.md b/docs/api/DevElf/TypeExtensions.md new file mode 100644 index 0000000..c1e48fe --- /dev/null +++ b/docs/api/DevElf/TypeExtensions.md @@ -0,0 +1,27 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions') + +## TypeExtensions Class + +Provides extension methods for [System\.Type](https://learn.microsoft.com/en-us/dotnet/api/system.type 'System\.Type') to simplify type name formatting +and type analysis operations\. + +```csharp +public static class TypeExtensions +``` + +Inheritance [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') 🡒 TypeExtensions + +| Methods | | +| :--- | :--- | +| [get\_BuiltInTypeAliasMap\(\)](TypeExtensions.get_BuiltInTypeAliasMap().md 'DevElf\.Extensions\.TypeExtensions\.get\_BuiltInTypeAliasMap\(\)') | Gets the dictionary mapping built\-in types to their C\# keyword aliases\. | +| [GetCustomFormattedTypeFullName\(this Type, string, string\)](TypeExtensions.GetCustomFormattedTypeFullName.P76O9STWHPAGRI25QVIUQ5MVD.md 'DevElf\.Extensions\.TypeExtensions\.GetCustomFormattedTypeFullName\(this System\.Type, string, string\)') | Gets a formatted full name for the type using a custom format string\. | +| [GetCustomFormattedTypeName\(this Type, string, string, bool\)](TypeExtensions.GetCustomFormattedTypeName.IAF1XPCUI7NL3R5U5999O4SM4.md 'DevElf\.Extensions\.TypeExtensions\.GetCustomFormattedTypeName\(this System\.Type, string, string, bool\)') | Gets a formatted name for the type using a custom format string\. | +| [GetFriendlyTypeFullName\(this Type\)](TypeExtensions.GetFriendlyTypeFullName.TGDWG5RWDUJW2KUFF1GSUH52B.md 'DevElf\.Extensions\.TypeExtensions\.GetFriendlyTypeFullName\(this System\.Type\)') | Gets a friendly, readable full name for the type using angle bracket notation for generic types\. | +| [GetFriendlyTypeName\(this Type, bool\)](TypeExtensions.GetFriendlyTypeName.J35G2Y7DEMNMKUW3HYFEJQRE4.md 'DevElf\.Extensions\.TypeExtensions\.GetFriendlyTypeName\(this System\.Type, bool\)') | Gets a friendly, readable name for the type using angle bracket notation for generic types\. | +| [GetNameWithoutGenericParameters\(this Type\)](TypeExtensions.GetNameWithoutGenericParameters.W1YHOUP03743XOTR3ULZTUPA6.md 'DevElf\.Extensions\.TypeExtensions\.GetNameWithoutGenericParameters\(this System\.Type\)') | Gets the name of the type without generic parameter indicators\. | +| [GetTypeName\(this Type, bool\)](TypeExtensions.GetTypeName.UH859SB3JKYGI29AZPHHWSOT5.md 'DevElf\.Extensions\.TypeExtensions\.GetTypeName\(this System\.Type, bool\)') | Gets the name of the type, optionally using C\# keyword aliases for built\-in types\. | +| [IsIEnumerableOfT\(this Type, bool\)](TypeExtensions.IsIEnumerableOfT.94FI3DNSKIQR77KQEYY3O9VJ6.md 'DevElf\.Extensions\.TypeExtensions\.IsIEnumerableOfT\(this System\.Type, bool\)') | Determines whether the specified type implements [System\.Collections\.Generic\.IEnumerable<>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 'System\.Collections\.Generic\.IEnumerable\`1')\. | +| [IsStatic\(this Type\)](TypeExtensions.IsStatic.3K24BJS6E9QC8MFS6MLNUI3FA.md 'DevElf\.Extensions\.TypeExtensions\.IsStatic\(this System\.Type\)') | Determines whether the specified type is a static class\. | +| [TryGetIEnumerableOfTType\(this Type, Type, bool\)](TypeExtensions.TryGetIEnumerableOfTType.0M5ESH17YJABIKN8X3RLK96BC.md 'DevElf\.Extensions\.TypeExtensions\.TryGetIEnumerableOfTType\(this System\.Type, System\.Type, bool\)') | Attempts to get the [System\.Collections\.Generic\.IEnumerable<>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 'System\.Collections\.Generic\.IEnumerable\`1') interface type from a type that implements it\. | +| [TryGetTypeOfTFromIEnumerableOfT\(this Type, Type, bool\)](TypeExtensions.TryGetTypeOfTFromIEnumerableOfT.W0NGC76YSUAP62VXD2CX03CT1.md 'DevElf\.Extensions\.TypeExtensions\.TryGetTypeOfTFromIEnumerableOfT\(this System\.Type, System\.Type, bool\)') | Attempts to get the element type T from a type that implements [System\.Collections\.Generic\.IEnumerable<>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 'System\.Collections\.Generic\.IEnumerable\`1')\. | diff --git a/src/DevElf.Logging/LogMessageScope.cs b/src/DevElf.Logging/LogMessageScope.cs index 034ba2d..4198495 100644 --- a/src/DevElf.Logging/LogMessageScope.cs +++ b/src/DevElf.Logging/LogMessageScope.cs @@ -15,11 +15,11 @@ namespace DevElf.Logging; /// While active, a scope can accumulate key/value properties via . /// When scopes are nested, properties are merged so that child properties override parent values for the /// same key. On , the scope logs its message at the configured , -/// using with the accumulated properties so they are available to +/// using with the accumulated properties so they are available to /// logging providers that support scopes. /// /// An exception can be associated to the log entry via and will be -/// passed to . When setAsProperty is +/// passed to the logger when the scope is disposed. When setAsProperty is /// , the exception is also added as a scope property under the key "Exception". /// internal sealed partial class LogMessageScope : IDisposable, ILogMessageScope diff --git a/src/DevElf/Extensions/TypeExtensions.cs b/src/DevElf/Extensions/TypeExtensions.cs new file mode 100644 index 0000000..0489352 --- /dev/null +++ b/src/DevElf/Extensions/TypeExtensions.cs @@ -0,0 +1,324 @@ +using System.Collections.Frozen; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using DevElf.ArgumentValidation; + +namespace DevElf.Extensions; + +/// +/// Provides extension methods for to simplify type name formatting +/// and type analysis operations. +/// +public static class TypeExtensions +{ + private static readonly FrozenDictionary BuiltInTypeAliasMap = new Dictionary + { + [typeof(bool)] = "bool", + [typeof(byte)] = "byte", + [typeof(sbyte)] = "sbyte", + [typeof(char)] = "char", + [typeof(decimal)] = "decimal", + [typeof(double)] = "double", + [typeof(float)] = "float", + [typeof(int)] = "int", + [typeof(uint)] = "uint", + [typeof(long)] = "long", + [typeof(ulong)] = "ulong", + [typeof(object)] = "object", + [typeof(short)] = "short", + [typeof(ushort)] = "ushort", + [typeof(string)] = "string", + }.ToFrozenDictionary(); + +#pragma warning disable CA1034 // Nested types should not be visible + + extension(Type) + { + /// + /// Gets the dictionary mapping built-in types to their C# keyword aliases. + /// + public static IReadOnlyDictionary BuiltInTypeAliasMap => BuiltInTypeAliasMap; + } + +#pragma warning restore CA1034 // Nested types should not be visible + + /// + /// Gets a friendly, readable name for the type using angle bracket notation for generic + /// types. + /// + /// The type to format. + /// + /// to use C# keyword aliases for built-in types; + /// otherwise, . + /// + /// + /// A string representing the type name. For generic types, returns the format + /// "TypeName<T1, T2>". For non-generic types, returns the simple type name. + /// + public static string GetFriendlyTypeName(this Type type, bool useBuiltInTypeNameAliases = false) + => type.GetCustomFormattedTypeName("{0}<{1}>", ", ", useBuiltInTypeNameAliases); + + /// + /// Gets a formatted name for the type using a custom format string. + /// + /// The type to format. + /// + /// The format string where {0} is the base type name and {1} is the generic arguments. + /// For non-generic types, only {0} is used. + /// + /// + /// The string used to separate generic type arguments. Default is ", ". + /// + /// + /// to use C# keyword aliases for built-in types; + /// otherwise, . + /// + /// + /// A formatted string representation of the type name. For non-generic types, returns + /// the simple type name. + /// + public static string GetCustomFormattedTypeName( + this Type type, + string format, + string argumentSeparator = ", ", + bool useBuiltInTypeNameAliases = false) + { + type.ThrowIfNull(); + format.ThrowIfNull(); + + if (!type.IsGenericType) + { + return GetTypeName(type, useBuiltInTypeNameAliases); + } + + string baseTypeName = GetTypeName(type, useBuiltInTypeNameAliases); + + if (baseTypeName.Contains('`', StringComparison.Ordinal)) + { + baseTypeName = baseTypeName[..baseTypeName.IndexOf('`', StringComparison.Ordinal)]; + } + + Type[] genericArguments = type.GetGenericArguments(); + string argumentNames = string.Join( + argumentSeparator, + genericArguments.Select(arg => arg.GetCustomFormattedTypeName(format, argumentSeparator, useBuiltInTypeNameAliases))); + + return string.Format(CultureInfo.InvariantCulture, format, baseTypeName, argumentNames); + } + + /// + /// Gets the name of the type, optionally using C# keyword aliases for built-in types. + /// + /// The type to get the name from. + /// + /// to use C# keyword aliases for built-in types; + /// otherwise, . + /// + /// The name of the type. + public static string GetTypeName(this Type type, bool useBuiltInTypeNameAliases = false) + { + type.ThrowIfNull(); + + return !useBuiltInTypeNameAliases + ? type.Name + : BuiltInTypeAliasMap.TryGetValue(type, out string? alias) + ? alias + : type.Name; + } + + /// + /// Gets a friendly, readable full name for the type using angle bracket notation for + /// generic types. + /// + /// The type to format. + /// + /// A string representing the type full name. For generic types, returns the format + /// "Namespace.TypeName<T1, T2>". For non-generic types, returns the full type + /// name. + /// + public static string GetFriendlyTypeFullName(this Type type) + => type.GetCustomFormattedTypeFullName("{0}<{1}>"); + + /// + /// Gets a formatted full name for the type using a custom format string. + /// + /// The type to format. + /// + /// The format string where {0} is the base type full name and {1} is the generic + /// arguments. For non-generic types, only {0} is used. + /// + /// + /// The string used to separate generic type arguments. Default is ", ". + /// + /// + /// A formatted string representation of the type full name. For non-generic types, + /// returns the full type name. + /// + public static string GetCustomFormattedTypeFullName(this Type type, string format, string argumentSeparator = ", ") + { + type.ThrowIfNull(); + format.ThrowIfNull(); + + if (!type.IsGenericType) + { + return type.FullName ?? type.Name; + } + + string baseTypeName = type.FullName?[..type.FullName.IndexOf('`', StringComparison.Ordinal)] + ?? type.Name[..type.Name.IndexOf('`', StringComparison.Ordinal)]; + Type[] genericArguments = type.GetGenericArguments(); + string argumentNames = string.Join(argumentSeparator, genericArguments.Select(arg => arg.GetCustomFormattedTypeFullName(format, argumentSeparator))); + + return string.Format(CultureInfo.InvariantCulture, format, baseTypeName, argumentNames); + } + + /// + /// Gets the name of the type without generic parameter indicators. + /// + /// The type to get the name from. + /// + /// The type name without the generic parameter count indicator (e.g., "List" instead + /// of "List`1"). + /// + public static string GetNameWithoutGenericParameters(this Type type) + { + type.ThrowIfNull(); + + return !type.IsGenericType + ? type.Name + : type.Name[..type.Name.IndexOf('`', StringComparison.Ordinal)]; + } + + /// + /// Determines whether the specified type is a static class. + /// + /// The type to check. + /// + /// if the type is a static class; otherwise, + /// . + /// + public static bool IsStatic(this Type type) + { + type.ThrowIfNull(); + + return type.IsAbstract && type.IsSealed; + } + + /// + /// Determines whether the specified type implements + /// . + /// + /// The type to check. + /// + /// to exclude from being considered as + /// ; otherwise, . + /// + /// + /// if the type implements ; + /// otherwise, . + /// + public static bool IsIEnumerableOfT( + this Type type, + bool excludeString = false) + { + type.ThrowIfNull(); + + if (excludeString && type == typeof(string)) + { + return false; + } + + // check if the type itself is IEnumerable + if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>)) + { + return true; + } + + // check if the type implements IEnumerable + return type.GetInterfaces().Any(interfaceType => + interfaceType.IsGenericType + && interfaceType.GetGenericTypeDefinition() == typeof(IEnumerable<>)); + } + + /// + /// Attempts to get the element type T from a type that implements + /// . + /// + /// The type to check. + /// + /// When this method returns, contains the element type T if the type implements + /// ; otherwise, . + /// + /// + /// to exclude from being considered as + /// ; otherwise, . + /// + /// + /// if the type implements and + /// the element type was retrieved; otherwise, . + /// + public static bool TryGetTypeOfTFromIEnumerableOfT( + this Type type, + [NotNullWhen(true)] out Type? typeOfT, + bool excludeString = false) + { + type.ThrowIfNull(); + + typeOfT = null; + + if (type.TryGetIEnumerableOfTType(out Type? enumerableInterfaceType, excludeString)) + { + typeOfT = enumerableInterfaceType.GetGenericArguments().FirstOrDefault(); + } + + return typeOfT != null; + } + + /// + /// Attempts to get the interface type from a type that + /// implements it. + /// + /// The type to check. + /// + /// When this method returns, contains the interface + /// type if the type implements it; otherwise, . + /// + /// + /// to exclude from being considered as + /// ; otherwise, . + /// + /// + /// if the type implements ; + /// otherwise, . + /// + public static bool TryGetIEnumerableOfTType( + this Type type, + [NotNullWhen(true)] out Type? enumerableInterfaceType, + bool excludeString = false) + { + type.ThrowIfNull(); + + enumerableInterfaceType = null; + + if (excludeString && type == typeof(string)) + { + return false; + } + + // check if the type itself is IEnumerable + if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>)) + { + enumerableInterfaceType = type; + + return true; + } + + // check if the type implements IEnumerable + enumerableInterfaceType = type.GetInterfaces() + .FirstOrDefault(@interface => + @interface.IsGenericType + && @interface.GetGenericTypeDefinition() == typeof(IEnumerable<>)); + + return enumerableInterfaceType != null; + } +} diff --git a/tests/DevElf.Tests/Extensions/TypeExtensionsTests.cs b/tests/DevElf.Tests/Extensions/TypeExtensionsTests.cs new file mode 100644 index 0000000..ec0a780 --- /dev/null +++ b/tests/DevElf.Tests/Extensions/TypeExtensionsTests.cs @@ -0,0 +1,692 @@ +using AwesomeAssertions; +using DevElf.Extensions; + +namespace DevElf.Tests.Extensions; + +[TestClass] +public class TypeExtensionsTests +{ + [TestMethod] + public void GetTypeName_returns_type_name_when_useBuiltInTypeNameAliases_is_false() + { + // Arrange + Type type = typeof(int); + + // Act + string result = type.GetTypeName(useBuiltInTypeNameAliases: false); + + // Assert + _ = result.Should().Be("Int32"); + } + + [TestMethod] + public void GetTypeName_returns_alias_when_useBuiltInTypeNameAliases_is_true() + { + // Arrange + Type type = typeof(int); + + // Act + string result = type.GetTypeName(useBuiltInTypeNameAliases: true); + + // Assert + _ = result.Should().Be("int"); + } + + [TestMethod] + public void GetTypeName_returns_type_name_for_non_built_in_type() + { + // Arrange + Type type = typeof(TypeExtensionsTests); + + // Act + string result = type.GetTypeName(useBuiltInTypeNameAliases: true); + + // Assert + _ = result.Should().Be("TypeExtensionsTests"); + } + + [TestMethod] + public void GetTypeName_returns_bool_alias() + { + // Arrange + Type type = typeof(bool); + + // Act + string result = type.GetTypeName(useBuiltInTypeNameAliases: true); + + // Assert + _ = result.Should().Be("bool"); + } + + [TestMethod] + public void GetTypeName_returns_string_alias() + { + // Arrange + Type type = typeof(string); + + // Act + string result = type.GetTypeName(useBuiltInTypeNameAliases: true); + + // Assert + _ = result.Should().Be("string"); + } + + [TestMethod] + public void GetTypeName_throws_when_type_is_null() + { + // Arrange + Type type = null!; + + // Act + Action act = () => type.GetTypeName(); + + // Assert + _ = act.Should().Throw(); + } + + [TestMethod] + public void GetFriendlyTypeName_returns_formatted_generic_type_name() + { + // Arrange + Type type = typeof(List); + + // Act + string result = type.GetFriendlyTypeName(); + + // Assert + _ = result.Should().Be("List"); + } + + [TestMethod] + public void GetFriendlyTypeName_returns_formatted_generic_type_name_with_aliases() + { + // Arrange + Type type = typeof(List); + + // Act + string result = type.GetFriendlyTypeName(useBuiltInTypeNameAliases: true); + + // Assert + _ = result.Should().Be("List"); + } + + [TestMethod] + public void GetFriendlyTypeName_returns_formatted_nested_generic_type_name() + { + // Arrange + Type type = typeof(Dictionary>); + + // Act + string result = type.GetFriendlyTypeName(useBuiltInTypeNameAliases: true); + + // Assert + _ = result.Should().Be("Dictionary>"); + } + + [TestMethod] + public void GetFriendlyTypeName_returns_simple_name_for_non_generic_type() + { + // Arrange + Type type = typeof(int); + + // Act + string result = type.GetFriendlyTypeName(); + + // Assert + _ = result.Should().Be("Int32"); + } + + [TestMethod] + public void GetFriendlyTypeName_throws_when_type_is_null() + { + // Arrange + Type type = null!; + + // Act + Action act = () => type.GetFriendlyTypeName(); + + // Assert + _ = act.Should().Throw(); + } + + [TestMethod] + public void GetCustomFormattedTypeName_returns_formatted_type_name_with_custom_format() + { + // Arrange + Type type = typeof(List); + + // Act + string result = type.GetCustomFormattedTypeName("[{0}[{1}]]", ";"); + + // Assert + _ = result.Should().Be("[List[Int32]]"); + } + + [TestMethod] + public void GetCustomFormattedTypeName_returns_formatted_type_name_with_multiple_arguments() + { + // Arrange + Type type = typeof(Dictionary); + + // Act + string result = type.GetCustomFormattedTypeName("{0}<{1}>", " | ", useBuiltInTypeNameAliases: true); + + // Assert + _ = result.Should().Be("Dictionary"); + } + + [TestMethod] + public void GetCustomFormattedTypeName_throws_when_type_is_null() + { + // Arrange + Type type = null!; + + // Act + Action act = () => type.GetCustomFormattedTypeName("{0}<{1}>"); + + // Assert + _ = act.Should().Throw(); + } + + [TestMethod] + public void GetCustomFormattedTypeName_throws_when_format_is_null() + { + // Arrange + Type type = typeof(List); + string format = null!; + + // Act + Action act = () => type.GetCustomFormattedTypeName(format); + + // Assert + _ = act.Should().Throw(); + } + + [TestMethod] + public void GetFriendlyTypeFullName_returns_full_name_for_generic_type() + { + // Arrange + Type type = typeof(List); + + // Act + string result = type.GetFriendlyTypeFullName(); + + // Assert + _ = result.Should().Be("System.Collections.Generic.List"); + } + + [TestMethod] + public void GetFriendlyTypeFullName_returns_full_name_for_nested_generic_type() + { + // Arrange + Type type = typeof(Dictionary>); + + // Act + string result = type.GetFriendlyTypeFullName(); + + // Assert + _ = result.Should().Be("System.Collections.Generic.Dictionary>"); + } + + [TestMethod] + public void GetFriendlyTypeFullName_returns_full_name_for_non_generic_type() + { + // Arrange + Type type = typeof(int); + + // Act + string result = type.GetFriendlyTypeFullName(); + + // Assert + _ = result.Should().Be("System.Int32"); + } + + [TestMethod] + public void GetFriendlyTypeFullName_throws_when_type_is_null() + { + // Arrange + Type type = null!; + + // Act + Action act = () => type.GetFriendlyTypeFullName(); + + // Assert + _ = act.Should().Throw(); + } + + [TestMethod] + public void GetCustomFormattedTypeFullName_returns_formatted_full_name_with_custom_format() + { + // Arrange + Type type = typeof(List); + + // Act + string result = type.GetCustomFormattedTypeFullName("{0}[{1}]", ";"); + + // Assert + _ = result.Should().Be("System.Collections.Generic.List[System.Int32]"); + } + + [TestMethod] + public void GetCustomFormattedTypeFullName_throws_when_type_is_null() + { + // Arrange + Type type = null!; + + // Act + Action act = () => type.GetCustomFormattedTypeFullName("{0}<{1}>"); + + // Assert + _ = act.Should().Throw(); + } + + [TestMethod] + public void GetCustomFormattedTypeFullName_throws_when_format_is_null() + { + // Arrange + Type type = typeof(List); + string format = null!; + + // Act + Action act = () => type.GetCustomFormattedTypeFullName(format); + + // Assert + _ = act.Should().Throw(); + } + + [TestMethod] + public void GetNameWithoutGenericParameters_returns_name_without_generic_marker() + { + // Arrange + Type type = typeof(List); + + // Act + string result = type.GetNameWithoutGenericParameters(); + + // Assert + _ = result.Should().Be("List"); + } + + [TestMethod] + public void GetNameWithoutGenericParameters_returns_name_for_non_generic_type() + { + // Arrange + Type type = typeof(int); + + // Act + string result = type.GetNameWithoutGenericParameters(); + + // Assert + _ = result.Should().Be("Int32"); + } + + [TestMethod] + public void GetNameWithoutGenericParameters_returns_name_for_multiple_generic_parameters() + { + // Arrange + Type type = typeof(Dictionary); + + // Act + string result = type.GetNameWithoutGenericParameters(); + + // Assert + _ = result.Should().Be("Dictionary"); + } + + [TestMethod] + public void GetNameWithoutGenericParameters_throws_when_type_is_null() + { + // Arrange + Type type = null!; + + // Act + Action act = () => type.GetNameWithoutGenericParameters(); + + // Assert + _ = act.Should().Throw(); + } + + [TestMethod] + public void IsStatic_returns_true_for_static_class() + { + // Arrange + Type type = typeof(StaticTestClass); + + // Act + bool result = type.IsStatic(); + + // Assert + _ = result.Should().BeTrue(); + } + + [TestMethod] + public void IsStatic_returns_false_for_non_static_class() + { + // Arrange + Type type = typeof(NonStaticTestClass); + + // Act + bool result = type.IsStatic(); + + // Assert + _ = result.Should().BeFalse(); + } + + [TestMethod] + public void IsStatic_returns_false_for_abstract_class() + { + // Arrange + Type type = typeof(AbstractTestClass); + + // Act + bool result = type.IsStatic(); + + // Assert + _ = result.Should().BeFalse(); + } + + [TestMethod] + public void IsStatic_throws_when_type_is_null() + { + // Arrange + Type type = null!; + + // Act + Action act = () => type.IsStatic(); + + // Assert + _ = act.Should().Throw(); + } + + [TestMethod] + public void IsIEnumerableOfT_returns_true_for_list() + { + // Arrange + Type type = typeof(List); + + // Act + bool result = type.IsIEnumerableOfT(); + + // Assert + _ = result.Should().BeTrue(); + } + + [TestMethod] + public void IsIEnumerableOfT_returns_true_for_array() + { + // Arrange + Type type = typeof(int[]); + + // Act + bool result = type.IsIEnumerableOfT(); + + // Assert + _ = result.Should().BeTrue(); + } + + [TestMethod] + public void IsIEnumerableOfT_returns_true_for_string_when_not_excluded() + { + // Arrange + Type type = typeof(string); + + // Act + bool result = type.IsIEnumerableOfT(excludeString: false); + + // Assert + _ = result.Should().BeTrue(); + } + + [TestMethod] + public void IsIEnumerableOfT_returns_false_for_string_when_excluded() + { + // Arrange + Type type = typeof(string); + + // Act + bool result = type.IsIEnumerableOfT(excludeString: true); + + // Assert + _ = result.Should().BeFalse(); + } + + [TestMethod] + public void IsIEnumerableOfT_returns_false_for_int() + { + // Arrange + Type type = typeof(int); + + // Act + bool result = type.IsIEnumerableOfT(); + + // Assert + _ = result.Should().BeFalse(); + } + + [TestMethod] + public void IsIEnumerableOfT_returns_true_for_IEnumerable_interface() + { + // Arrange + Type type = typeof(IEnumerable); + + // Act + bool result = type.IsIEnumerableOfT(); + + // Assert + _ = result.Should().BeTrue(); + } + + [TestMethod] + public void IsIEnumerableOfT_throws_when_type_is_null() + { + // Arrange + Type type = null!; + + // Act + Action act = () => type.IsIEnumerableOfT(); + + // Assert + _ = act.Should().Throw(); + } + + [TestMethod] + public void TryGetTypeOfTFromIEnumerableOfT_returns_true_and_gets_element_type_for_list() + { + // Arrange + Type type = typeof(List); + + // Act + bool result = type.TryGetTypeOfTFromIEnumerableOfT(out Type? elementType); + + // Assert + _ = result.Should().BeTrue(); + _ = elementType.Should().Be(); + } + + [TestMethod] + public void TryGetTypeOfTFromIEnumerableOfT_returns_true_and_gets_element_type_for_array() + { + // Arrange + Type type = typeof(string[]); + + // Act + bool result = type.TryGetTypeOfTFromIEnumerableOfT(out Type? elementType); + + // Assert + _ = result.Should().BeTrue(); + _ = elementType.Should().Be(); + } + + [TestMethod] + public void TryGetTypeOfTFromIEnumerableOfT_returns_true_for_string_when_not_excluded() + { + // Arrange + Type type = typeof(string); + + // Act + bool result = type.TryGetTypeOfTFromIEnumerableOfT(out Type? elementType, excludeString: false); + + // Assert + _ = result.Should().BeTrue(); + _ = elementType.Should().Be(); + } + + [TestMethod] + public void TryGetTypeOfTFromIEnumerableOfT_returns_false_for_string_when_excluded() + { + // Arrange + Type type = typeof(string); + + // Act + bool result = type.TryGetTypeOfTFromIEnumerableOfT(out Type? elementType, excludeString: true); + + // Assert + _ = result.Should().BeFalse(); + _ = elementType.Should().BeNull(); + } + + [TestMethod] + public void TryGetTypeOfTFromIEnumerableOfT_returns_false_for_int() + { + // Arrange + Type type = typeof(int); + + // Act + bool result = type.TryGetTypeOfTFromIEnumerableOfT(out Type? elementType); + + // Assert + _ = result.Should().BeFalse(); + _ = elementType.Should().BeNull(); + } + + [TestMethod] + public void TryGetTypeOfTFromIEnumerableOfT_returns_true_for_IEnumerable_interface() + { + // Arrange + Type type = typeof(IEnumerable); + + // Act + bool result = type.TryGetTypeOfTFromIEnumerableOfT(out Type? elementType); + + // Assert + _ = result.Should().BeTrue(); + _ = elementType.Should().Be(); + } + + [TestMethod] + public void TryGetIEnumerableOfTType_returns_true_and_gets_interface_for_list() + { + // Arrange + Type type = typeof(List); + + // Act + bool result = type.TryGetIEnumerableOfTType(out Type? interfaceType); + + // Assert + _ = result.Should().BeTrue(); + _ = interfaceType.Should().NotBeNull(); + _ = interfaceType!.GetGenericTypeDefinition().Should().Be(typeof(IEnumerable<>)); + } + + [TestMethod] + public void TryGetIEnumerableOfTType_returns_true_and_gets_interface_for_array() + { + // Arrange + Type type = typeof(double[]); + + // Act + bool result = type.TryGetIEnumerableOfTType(out Type? interfaceType); + + // Assert + _ = result.Should().BeTrue(); + _ = interfaceType.Should().NotBeNull(); + } + + [TestMethod] + public void TryGetIEnumerableOfTType_returns_true_for_string_when_not_excluded() + { + // Arrange + Type type = typeof(string); + + // Act + bool result = type.TryGetIEnumerableOfTType(out Type? interfaceType, excludeString: false); + + // Assert + _ = result.Should().BeTrue(); + _ = interfaceType.Should().NotBeNull(); + } + + [TestMethod] + public void TryGetIEnumerableOfTType_returns_false_for_string_when_excluded() + { + // Arrange + Type type = typeof(string); + + // Act + bool result = type.TryGetIEnumerableOfTType(out Type? interfaceType, excludeString: true); + + // Assert + _ = result.Should().BeFalse(); + _ = interfaceType.Should().BeNull(); + } + + [TestMethod] + public void TryGetIEnumerableOfTType_returns_false_for_int() + { + // Arrange + Type type = typeof(int); + + // Act + bool result = type.TryGetIEnumerableOfTType(out Type? interfaceType); + + // Assert + _ = result.Should().BeFalse(); + _ = interfaceType.Should().BeNull(); + } + + [TestMethod] + public void TryGetIEnumerableOfTType_throws_when_type_is_null() + { + // Arrange + Type type = null!; + + // Act + Action act = () => type.TryGetIEnumerableOfTType(out _); + + // Assert + _ = act.Should().Throw(); + } + + [TestMethod] + public void GetTypeName_returns_all_built_in_type_aliases() + { + // Arrange & Act & Assert + _ = typeof(bool).GetTypeName(useBuiltInTypeNameAliases: true).Should().Be("bool"); + _ = typeof(byte).GetTypeName(useBuiltInTypeNameAliases: true).Should().Be("byte"); + _ = typeof(sbyte).GetTypeName(useBuiltInTypeNameAliases: true).Should().Be("sbyte"); + _ = typeof(char).GetTypeName(useBuiltInTypeNameAliases: true).Should().Be("char"); + _ = typeof(decimal).GetTypeName(useBuiltInTypeNameAliases: true).Should().Be("decimal"); + _ = typeof(double).GetTypeName(useBuiltInTypeNameAliases: true).Should().Be("double"); + _ = typeof(float).GetTypeName(useBuiltInTypeNameAliases: true).Should().Be("float"); + _ = typeof(int).GetTypeName(useBuiltInTypeNameAliases: true).Should().Be("int"); + _ = typeof(uint).GetTypeName(useBuiltInTypeNameAliases: true).Should().Be("uint"); + _ = typeof(long).GetTypeName(useBuiltInTypeNameAliases: true).Should().Be("long"); + _ = typeof(ulong).GetTypeName(useBuiltInTypeNameAliases: true).Should().Be("ulong"); + _ = typeof(object).GetTypeName(useBuiltInTypeNameAliases: true).Should().Be("object"); + _ = typeof(short).GetTypeName(useBuiltInTypeNameAliases: true).Should().Be("short"); + _ = typeof(ushort).GetTypeName(useBuiltInTypeNameAliases: true).Should().Be("ushort"); + _ = typeof(string).GetTypeName(useBuiltInTypeNameAliases: true).Should().Be("string"); + } + + private static class StaticTestClass + { + } + + private class NonStaticTestClass + { + } + + private abstract class AbstractTestClass + { + } +} From f1b956295f65c402b2ec868def2f0089fd0d9866 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Luis=20Barreda=20G=C3=BCere=C3=B1a?= Date: Sat, 11 Oct 2025 01:42:46 -0700 Subject: [PATCH 2/6] feat: add round-robin generators and exception wrapper Introduced `IRoundRobinGenerator` interface and two implementations: - `RoundRobinGeneratorBase`: Base class for round-robin generators. - `RoundRobinNumberGenerator`: Numeric round-robin generator. Added `SerializableExceptionWrapper` for serializing exceptions, including properties and inner exceptions. Updated `.editorconfig` and `copilot-instructions.md` to enforce consistent coding styles and guidelines. Refactored private field naming conventions in `LogMessageScope` and `FrozenTimeProvider`. Added comprehensive tests for round-robin generators and exception wrapper. --- .editorconfig | 8 +- .github/copilot-instructions.md | 26 +++++- docs/api/DevElf/DevElf.md | 7 ++ .../IRoundRobinGenerator_T_.NextValue().md | 14 +++ docs/api/DevElf/IRoundRobinGenerator_T_.md | 26 ++++++ ...Base_T_..ctor.E1NI20SLHJC7G3YEVMRF0XE53.md | 34 ++++++++ ..._T_.Increment.1YMOTJ0TC8DKL0BR7911JNZT1.md | 21 +++++ .../RoundRobinGeneratorBase_T_.NextValue().md | 16 ++++ docs/api/DevElf/RoundRobinGeneratorBase_T_.md | 31 +++++++ ...ator_T_..ctor.BQ7SXSX0RJJGA8DO29J5OPPQ6.md | 28 ++++++ ...oundRobinNumberGenerator_T_.NextValue().md | 16 ++++ .../DevElf/RoundRobinNumberGenerator_T_.md | 30 +++++++ ...Wrapper..ctor.LZH9UCLTN28N35I70OCL3GM65.md | 22 +++++ .../SerializableExceptionWrapper.Data.md | 13 +++ .../SerializableExceptionWrapper.HResult.md | 13 +++ .../SerializableExceptionWrapper.HelpLink.md | 13 +++ ...alizableExceptionWrapper.InnerException.md | 13 +++ .../SerializableExceptionWrapper.Message.md | 13 +++ .../SerializableExceptionWrapper.Source.md | 13 +++ ...SerializableExceptionWrapper.StackTrace.md | 13 +++ ...SerializableExceptionWrapper.ToString().md | 14 +++ .../DevElf/SerializableExceptionWrapper.md | 30 +++++++ src/DevElf.Logging/LogMessageScope.cs | 46 +++++----- src/DevElf/FrozenTimeProvider.cs | 8 +- src/DevElf/IRoundRobinGenerator.cs | 15 ++++ src/DevElf/RoundRobinGeneratorBase.cs | 67 ++++++++++++++ src/DevElf/RoundRobinNumberGenerator.cs | 57 ++++++++++++ src/DevElf/SerializableExceptionWrapper.cs | 87 +++++++++++++++++++ .../LogMessageScopeManualTests.cs | 12 +-- .../RoundRobinGeneratorBaseTests.cs | 57 ++++++++++++ .../RoundRobinNumberGeneratorTests.cs | 53 +++++++++++ .../SerializableExceptionWrapperTests.cs | 79 +++++++++++++++++ 32 files changed, 853 insertions(+), 42 deletions(-) create mode 100644 docs/api/DevElf/IRoundRobinGenerator_T_.NextValue().md create mode 100644 docs/api/DevElf/IRoundRobinGenerator_T_.md create mode 100644 docs/api/DevElf/RoundRobinGeneratorBase_T_..ctor.E1NI20SLHJC7G3YEVMRF0XE53.md create mode 100644 docs/api/DevElf/RoundRobinGeneratorBase_T_.Increment.1YMOTJ0TC8DKL0BR7911JNZT1.md create mode 100644 docs/api/DevElf/RoundRobinGeneratorBase_T_.NextValue().md create mode 100644 docs/api/DevElf/RoundRobinGeneratorBase_T_.md create mode 100644 docs/api/DevElf/RoundRobinNumberGenerator_T_..ctor.BQ7SXSX0RJJGA8DO29J5OPPQ6.md create mode 100644 docs/api/DevElf/RoundRobinNumberGenerator_T_.NextValue().md create mode 100644 docs/api/DevElf/RoundRobinNumberGenerator_T_.md create mode 100644 docs/api/DevElf/SerializableExceptionWrapper..ctor.LZH9UCLTN28N35I70OCL3GM65.md create mode 100644 docs/api/DevElf/SerializableExceptionWrapper.Data.md create mode 100644 docs/api/DevElf/SerializableExceptionWrapper.HResult.md create mode 100644 docs/api/DevElf/SerializableExceptionWrapper.HelpLink.md create mode 100644 docs/api/DevElf/SerializableExceptionWrapper.InnerException.md create mode 100644 docs/api/DevElf/SerializableExceptionWrapper.Message.md create mode 100644 docs/api/DevElf/SerializableExceptionWrapper.Source.md create mode 100644 docs/api/DevElf/SerializableExceptionWrapper.StackTrace.md create mode 100644 docs/api/DevElf/SerializableExceptionWrapper.ToString().md create mode 100644 docs/api/DevElf/SerializableExceptionWrapper.md create mode 100644 src/DevElf/IRoundRobinGenerator.cs create mode 100644 src/DevElf/RoundRobinGeneratorBase.cs create mode 100644 src/DevElf/RoundRobinNumberGenerator.cs create mode 100644 src/DevElf/SerializableExceptionWrapper.cs create mode 100644 tests/DevElf.Tests/RoundRobinGeneratorBaseTests.cs create mode 100644 tests/DevElf.Tests/RoundRobinNumberGeneratorTests.cs create mode 100644 tests/DevElf.Tests/SerializableExceptionWrapperTests.cs diff --git a/.editorconfig b/.editorconfig index e942071..ae65f1a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -52,7 +52,7 @@ file_header_template = unset # this. and Me. preferences dotnet_style_qualification_for_event = false:warning -dotnet_style_qualification_for_field = false +dotnet_style_qualification_for_field = true:warning dotnet_style_qualification_for_method = false:warning dotnet_style_qualification_for_property = false:warning @@ -231,8 +231,6 @@ csharp_preserve_single_line_statements = false # Styles dotnet_naming_style.pascal_case_style.capitalization = pascal_case dotnet_naming_style.camel_case_style.capitalization = camel_case -dotnet_naming_style.underscore_prefix_style.capitalization = camel_case -dotnet_naming_style.underscore_prefix_style.required_prefix = _ # Symbols dotnet_naming_symbols.all_types.applicable_kinds = class, struct, enum, interface, record @@ -265,10 +263,6 @@ dotnet_naming_rule.public_members_should_be_pascal_case.severity = suggestion dotnet_naming_rule.public_members_should_be_pascal_case.symbols = public_members dotnet_naming_rule.public_members_should_be_pascal_case.style = pascal_case_style -dotnet_naming_rule.private_fields_should_have_underscore_prefix.severity = suggestion -dotnet_naming_rule.private_fields_should_have_underscore_prefix.symbols = private_fields -dotnet_naming_rule.private_fields_should_have_underscore_prefix.style = underscore_prefix_style - ############################################################ # Disabled rules ############################################################ diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index f0061f6..ad32582 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -25,13 +25,29 @@ - Use documentation comments with summaries and parameter descriptions. - Use consistent naming rules for interfaces, type parameters, and fields. - Use static local functions and simplified `new` expressions. +- Make only high confidence suggestions when reviewing code changes. +- Write code with good maintainability practices, including comments on why certain design decisions were made. +- Handle edge cases and write clear exception handling. +- For libraries or external dependencies, mention their usage and purpose in comments. +- Insert a newline before the opening curly brace of any code block (e.g., after `if`, `for`, `while`, `foreach`, `using`, `try`, etc.). +- Ensure that the final return statement of a method is on its own line. +- Use pattern matching and switch expressions wherever possible. +- Use `nameof` instead of string literals when referring to member names. +- Ensure that XML doc comments are created for any public APIs. When applicable, include `` and `` documentation in the comments. --- +## C# Instructions +- Always use the latest version C#, currently C# 14 features. +- Write clear and concise comments for each function. + + ## C# Style Preferences +- Apply code-formatting style defined in `.editorconfig`. - Never add more than one class/interface/enum/struct per file. - Use PascalCase for public constants and static readonly fields. -- Use camelCase with and underscore prefix for private fields and local variables. +- Use camelCase for private fields and local variables. +- Use camelCase for private readonly fields. - Prefix interfaces with `I` and type parameters with `T`. - Use explicit types for built-in types (`string`, `int`, `bool`, etc.) - Use `var` for complex types when the type is obvious from the right side @@ -54,7 +70,7 @@ - Prefer `nameof` over `typeof` where applicable. - Use tuple swap syntax for swapping values. - Use static local functions where possible. -- Add an empty line before `return`, `throw`, `break`, `yield`, and `continue`, when it's not the only line. If the previous line is a comment, the empty line should be added before the comment. +- Add an empty line before `return`, `throw`, `break`, `yield`, and `continue`, when it's not the only line in a block. If the previous line is a comment and there's a code line before it, the empty line should be added before the comment. - Place a blank line between method declarations. - Avoid multiple statements on a single line. - Align parameters and arguments vertically with one level of indentation. @@ -65,6 +81,12 @@ - Don't add unnecessary using statements. - Always add an empty line between lines of code and statement blocks. +### Nullable Reference Types + +- Declare variables non-nullable, and check for `null` at entry points. +- Always use `is null` or `is not null` instead of `== null` or `!= null`. +- Trust the C# null annotations and don't add null checks when the type system says a value cannot be null. + ### Documentation Preferences - Use XML documentation comments for public members. - Keep the XML documentation comment lines length under 100 characters. diff --git a/docs/api/DevElf/DevElf.md b/docs/api/DevElf/DevElf.md index 883914a..5dfe0b3 100644 --- a/docs/api/DevElf/DevElf.md +++ b/docs/api/DevElf/DevElf.md @@ -5,3 +5,10 @@ | Classes | | | :--- | :--- | | [FrozenTimeProvider](FrozenTimeProvider.md 'DevElf\.FrozenTimeProvider') | A [System\.TimeProvider](https://learn.microsoft.com/en-us/dotnet/api/system.timeprovider 'System\.TimeProvider') that always returns a fixed point in time\. Useful for tests and deterministic time\-dependent logic\. | +| [RoundRobinGeneratorBase<T>](RoundRobinGeneratorBase_T_.md 'DevElf\.RoundRobinGeneratorBase\') | Provides a base implementation for round\-robin generators using a comparer\. | +| [RoundRobinNumberGenerator<T>](RoundRobinNumberGenerator_T_.md 'DevElf\.RoundRobinNumberGenerator\') | Generates numbers in a round\-robin fashion between a start and end value\. | +| [SerializableExceptionWrapper](SerializableExceptionWrapper.md 'DevElf\.SerializableExceptionWrapper') | Wraps an [System\.Exception](https://learn.microsoft.com/en-us/dotnet/api/system.exception 'System\.Exception') for serialization, including its properties and inner exception\. | + +| Interfaces | | +| :--- | :--- | +| [IRoundRobinGenerator<T>](IRoundRobinGenerator_T_.md 'DevElf\.IRoundRobinGenerator\') | Defines a generator that produces values in a round\-robin sequence\. | diff --git a/docs/api/DevElf/IRoundRobinGenerator_T_.NextValue().md b/docs/api/DevElf/IRoundRobinGenerator_T_.NextValue().md new file mode 100644 index 0000000..4ef57ae --- /dev/null +++ b/docs/api/DevElf/IRoundRobinGenerator_T_.NextValue().md @@ -0,0 +1,14 @@ +#### [DevElf](README.md 'README') +### [DevElf](DevElf.md 'DevElf').[IRoundRobinGenerator<T>](IRoundRobinGenerator_T_.md 'DevElf\.IRoundRobinGenerator\') + +## IRoundRobinGenerator\\.NextValue\(\) Method + +Gets the next value in the round\-robin sequence\. + +```csharp +T NextValue(); +``` + +#### Returns +[T](IRoundRobinGenerator_T_.md#DevElf.IRoundRobinGenerator_T_.T 'DevElf\.IRoundRobinGenerator\\.T') +The next value in the sequence\. \ No newline at end of file diff --git a/docs/api/DevElf/IRoundRobinGenerator_T_.md b/docs/api/DevElf/IRoundRobinGenerator_T_.md new file mode 100644 index 0000000..3935026 --- /dev/null +++ b/docs/api/DevElf/IRoundRobinGenerator_T_.md @@ -0,0 +1,26 @@ +#### [DevElf](README.md 'README') +### [DevElf](DevElf.md 'DevElf') + +## IRoundRobinGenerator\ Interface + +Defines a generator that produces values in a round\-robin sequence\. + +```csharp +public interface IRoundRobinGenerator + where T : System.IComparable +``` +#### Type parameters + + + +`T` + +A type that implements [System\.IComparable<>](https://learn.microsoft.com/en-us/dotnet/api/system.icomparable-1 'System\.IComparable\`1')\. + +Derived +↳ [RoundRobinGeneratorBase<T>](RoundRobinGeneratorBase_T_.md 'DevElf\.RoundRobinGeneratorBase\') +↳ [RoundRobinNumberGenerator<T>](RoundRobinNumberGenerator_T_.md 'DevElf\.RoundRobinNumberGenerator\') + +| Methods | | +| :--- | :--- | +| [NextValue\(\)](IRoundRobinGenerator_T_.NextValue().md 'DevElf\.IRoundRobinGenerator\\.NextValue\(\)') | Gets the next value in the round\-robin sequence\. | diff --git a/docs/api/DevElf/RoundRobinGeneratorBase_T_..ctor.E1NI20SLHJC7G3YEVMRF0XE53.md b/docs/api/DevElf/RoundRobinGeneratorBase_T_..ctor.E1NI20SLHJC7G3YEVMRF0XE53.md new file mode 100644 index 0000000..5ee8683 --- /dev/null +++ b/docs/api/DevElf/RoundRobinGeneratorBase_T_..ctor.E1NI20SLHJC7G3YEVMRF0XE53.md @@ -0,0 +1,34 @@ +#### [DevElf](README.md 'README') +### [DevElf](DevElf.md 'DevElf').[RoundRobinGeneratorBase<T>](RoundRobinGeneratorBase_T_.md 'DevElf\.RoundRobinGeneratorBase\') + +## RoundRobinGeneratorBase\(T, T, IComparer\\) Constructor + +Initializes a new instance of the [RoundRobinGeneratorBase<T>](RoundRobinGeneratorBase_T_.md 'DevElf\.RoundRobinGeneratorBase\') class\. + +```csharp +protected RoundRobinGeneratorBase(T start, T end, System.Collections.Generic.IComparer? comparer=null); +``` +#### Parameters + + + +`start` [T](RoundRobinGeneratorBase_T_.md#DevElf.RoundRobinGeneratorBase_T_.T 'DevElf\.RoundRobinGeneratorBase\\.T') + +The starting value of the sequence\. + + + +`end` [T](RoundRobinGeneratorBase_T_.md#DevElf.RoundRobinGeneratorBase_T_.T 'DevElf\.RoundRobinGeneratorBase\\.T') + +The ending value of the sequence\. + + + +`comparer` [System\.Collections\.Generic\.IComparer<](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.icomparer-1 'System\.Collections\.Generic\.IComparer\`1')[T](RoundRobinGeneratorBase_T_.md#DevElf.RoundRobinGeneratorBase_T_.T 'DevElf\.RoundRobinGeneratorBase\\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.icomparer-1 'System\.Collections\.Generic\.IComparer\`1') + +The comparer to use for value comparison\. If [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null'), the default comparer is used\. + +#### Exceptions + +[System\.ArgumentException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentexception 'System\.ArgumentException') +Thrown if [start](RoundRobinGeneratorBase_T_..ctor.E1NI20SLHJC7G3YEVMRF0XE53.md#DevElf.RoundRobinGeneratorBase_T_.RoundRobinGeneratorBase(T,T,System.Collections.Generic.IComparer_T_).start 'DevElf\.RoundRobinGeneratorBase\\.RoundRobinGeneratorBase\(T, T, System\.Collections\.Generic\.IComparer\\)\.start') is greater than [end](RoundRobinGeneratorBase_T_..ctor.E1NI20SLHJC7G3YEVMRF0XE53.md#DevElf.RoundRobinGeneratorBase_T_.RoundRobinGeneratorBase(T,T,System.Collections.Generic.IComparer_T_).end 'DevElf\.RoundRobinGeneratorBase\\.RoundRobinGeneratorBase\(T, T, System\.Collections\.Generic\.IComparer\\)\.end')\. \ No newline at end of file diff --git a/docs/api/DevElf/RoundRobinGeneratorBase_T_.Increment.1YMOTJ0TC8DKL0BR7911JNZT1.md b/docs/api/DevElf/RoundRobinGeneratorBase_T_.Increment.1YMOTJ0TC8DKL0BR7911JNZT1.md new file mode 100644 index 0000000..2fa6231 --- /dev/null +++ b/docs/api/DevElf/RoundRobinGeneratorBase_T_.Increment.1YMOTJ0TC8DKL0BR7911JNZT1.md @@ -0,0 +1,21 @@ +#### [DevElf](README.md 'README') +### [DevElf](DevElf.md 'DevElf').[RoundRobinGeneratorBase<T>](RoundRobinGeneratorBase_T_.md 'DevElf\.RoundRobinGeneratorBase\') + +## RoundRobinGeneratorBase\\.Increment\(T\) Method + +Increments the value for the next round\-robin step\. + +```csharp +protected abstract T Increment(ref T value); +``` +#### Parameters + + + +`value` [T](RoundRobinGeneratorBase_T_.md#DevElf.RoundRobinGeneratorBase_T_.T 'DevElf\.RoundRobinGeneratorBase\\.T') + +The value to increment\. + +#### Returns +[T](RoundRobinGeneratorBase_T_.md#DevElf.RoundRobinGeneratorBase_T_.T 'DevElf\.RoundRobinGeneratorBase\\.T') +The incremented value\. \ No newline at end of file diff --git a/docs/api/DevElf/RoundRobinGeneratorBase_T_.NextValue().md b/docs/api/DevElf/RoundRobinGeneratorBase_T_.NextValue().md new file mode 100644 index 0000000..75a9370 --- /dev/null +++ b/docs/api/DevElf/RoundRobinGeneratorBase_T_.NextValue().md @@ -0,0 +1,16 @@ +#### [DevElf](README.md 'README') +### [DevElf](DevElf.md 'DevElf').[RoundRobinGeneratorBase<T>](RoundRobinGeneratorBase_T_.md 'DevElf\.RoundRobinGeneratorBase\') + +## RoundRobinGeneratorBase\\.NextValue\(\) Method + +Gets the next value in the round\-robin sequence\. + +```csharp +public T NextValue(); +``` + +Implements [NextValue\(\)](IRoundRobinGenerator_T_.NextValue().md 'DevElf\.IRoundRobinGenerator\\.NextValue\(\)') + +#### Returns +[T](RoundRobinGeneratorBase_T_.md#DevElf.RoundRobinGeneratorBase_T_.T 'DevElf\.RoundRobinGeneratorBase\\.T') +The next value in the sequence\. \ No newline at end of file diff --git a/docs/api/DevElf/RoundRobinGeneratorBase_T_.md b/docs/api/DevElf/RoundRobinGeneratorBase_T_.md new file mode 100644 index 0000000..31e73b3 --- /dev/null +++ b/docs/api/DevElf/RoundRobinGeneratorBase_T_.md @@ -0,0 +1,31 @@ +#### [DevElf](README.md 'README') +### [DevElf](DevElf.md 'DevElf') + +## RoundRobinGeneratorBase\ Class + +Provides a base implementation for round\-robin generators using a comparer\. + +```csharp +public abstract class RoundRobinGeneratorBase : DevElf.IRoundRobinGenerator + where T : System.IComparable +``` +#### Type parameters + + + +`T` + +A type implementing [System\.IComparable<>](https://learn.microsoft.com/en-us/dotnet/api/system.icomparable-1 'System\.IComparable\`1')\. + +Inheritance [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') 🡒 RoundRobinGeneratorBase\ + +Implements [DevElf\.IRoundRobinGenerator<](IRoundRobinGenerator_T_.md 'DevElf\.IRoundRobinGenerator\')[T](RoundRobinGeneratorBase_T_.md#DevElf.RoundRobinGeneratorBase_T_.T 'DevElf\.RoundRobinGeneratorBase\\.T')[>](IRoundRobinGenerator_T_.md 'DevElf\.IRoundRobinGenerator\') + +| Constructors | | +| :--- | :--- | +| [RoundRobinGeneratorBase\(T, T, IComparer<T>\)](RoundRobinGeneratorBase_T_..ctor.E1NI20SLHJC7G3YEVMRF0XE53.md 'DevElf\.RoundRobinGeneratorBase\\.RoundRobinGeneratorBase\(T, T, System\.Collections\.Generic\.IComparer\\)') | Initializes a new instance of the [RoundRobinGeneratorBase<T>](RoundRobinGeneratorBase_T_.md 'DevElf\.RoundRobinGeneratorBase\') class\. | + +| Methods | | +| :--- | :--- | +| [Increment\(T\)](RoundRobinGeneratorBase_T_.Increment.1YMOTJ0TC8DKL0BR7911JNZT1.md 'DevElf\.RoundRobinGeneratorBase\\.Increment\(T\)') | Increments the value for the next round\-robin step\. | +| [NextValue\(\)](RoundRobinGeneratorBase_T_.NextValue().md 'DevElf\.RoundRobinGeneratorBase\\.NextValue\(\)') | Gets the next value in the round\-robin sequence\. | diff --git a/docs/api/DevElf/RoundRobinNumberGenerator_T_..ctor.BQ7SXSX0RJJGA8DO29J5OPPQ6.md b/docs/api/DevElf/RoundRobinNumberGenerator_T_..ctor.BQ7SXSX0RJJGA8DO29J5OPPQ6.md new file mode 100644 index 0000000..d39be87 --- /dev/null +++ b/docs/api/DevElf/RoundRobinNumberGenerator_T_..ctor.BQ7SXSX0RJJGA8DO29J5OPPQ6.md @@ -0,0 +1,28 @@ +#### [DevElf](README.md 'README') +### [DevElf](DevElf.md 'DevElf').[RoundRobinNumberGenerator<T>](RoundRobinNumberGenerator_T_.md 'DevElf\.RoundRobinNumberGenerator\') + +## RoundRobinNumberGenerator\(T, T\) Constructor + +Initializes a new instance of the [RoundRobinNumberGenerator<T>](RoundRobinNumberGenerator_T_.md 'DevElf\.RoundRobinNumberGenerator\') class\. + +```csharp +public RoundRobinNumberGenerator(T start, T end); +``` +#### Parameters + + + +`start` [T](RoundRobinNumberGenerator_T_.md#DevElf.RoundRobinNumberGenerator_T_.T 'DevElf\.RoundRobinNumberGenerator\\.T') + +The starting value of the sequence\. + + + +`end` [T](RoundRobinNumberGenerator_T_.md#DevElf.RoundRobinNumberGenerator_T_.T 'DevElf\.RoundRobinNumberGenerator\\.T') + +The ending value of the sequence\. + +#### Exceptions + +[System\.ArgumentException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentexception 'System\.ArgumentException') +Thrown if [start](RoundRobinNumberGenerator_T_..ctor.BQ7SXSX0RJJGA8DO29J5OPPQ6.md#DevElf.RoundRobinNumberGenerator_T_.RoundRobinNumberGenerator(T,T).start 'DevElf\.RoundRobinNumberGenerator\\.RoundRobinNumberGenerator\(T, T\)\.start') is greater than [end](RoundRobinNumberGenerator_T_..ctor.BQ7SXSX0RJJGA8DO29J5OPPQ6.md#DevElf.RoundRobinNumberGenerator_T_.RoundRobinNumberGenerator(T,T).end 'DevElf\.RoundRobinNumberGenerator\\.RoundRobinNumberGenerator\(T, T\)\.end')\. \ No newline at end of file diff --git a/docs/api/DevElf/RoundRobinNumberGenerator_T_.NextValue().md b/docs/api/DevElf/RoundRobinNumberGenerator_T_.NextValue().md new file mode 100644 index 0000000..643c0ea --- /dev/null +++ b/docs/api/DevElf/RoundRobinNumberGenerator_T_.NextValue().md @@ -0,0 +1,16 @@ +#### [DevElf](README.md 'README') +### [DevElf](DevElf.md 'DevElf').[RoundRobinNumberGenerator<T>](RoundRobinNumberGenerator_T_.md 'DevElf\.RoundRobinNumberGenerator\') + +## RoundRobinNumberGenerator\\.NextValue\(\) Method + +Gets the next value in the round\-robin sequence\. + +```csharp +public T NextValue(); +``` + +Implements [NextValue\(\)](IRoundRobinGenerator_T_.NextValue().md 'DevElf\.IRoundRobinGenerator\\.NextValue\(\)') + +#### Returns +[T](RoundRobinNumberGenerator_T_.md#DevElf.RoundRobinNumberGenerator_T_.T 'DevElf\.RoundRobinNumberGenerator\\.T') +The next value in the sequence\. \ No newline at end of file diff --git a/docs/api/DevElf/RoundRobinNumberGenerator_T_.md b/docs/api/DevElf/RoundRobinNumberGenerator_T_.md new file mode 100644 index 0000000..1c2383c --- /dev/null +++ b/docs/api/DevElf/RoundRobinNumberGenerator_T_.md @@ -0,0 +1,30 @@ +#### [DevElf](README.md 'README') +### [DevElf](DevElf.md 'DevElf') + +## RoundRobinNumberGenerator\ Class + +Generates numbers in a round\-robin fashion between a start and end value\. + +```csharp +public class RoundRobinNumberGenerator : DevElf.IRoundRobinGenerator + where T : System.Numerics.INumber, System.IComparable +``` +#### Type parameters + + + +`T` + +A numeric type implementing [System\.Numerics\.INumber<>](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.inumber-1 'System\.Numerics\.INumber\`1') and [System\.IComparable<>](https://learn.microsoft.com/en-us/dotnet/api/system.icomparable-1 'System\.IComparable\`1')\. + +Inheritance [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') 🡒 RoundRobinNumberGenerator\ + +Implements [DevElf\.IRoundRobinGenerator<](IRoundRobinGenerator_T_.md 'DevElf\.IRoundRobinGenerator\')[T](RoundRobinNumberGenerator_T_.md#DevElf.RoundRobinNumberGenerator_T_.T 'DevElf\.RoundRobinNumberGenerator\\.T')[>](IRoundRobinGenerator_T_.md 'DevElf\.IRoundRobinGenerator\') + +| Constructors | | +| :--- | :--- | +| [RoundRobinNumberGenerator\(T, T\)](RoundRobinNumberGenerator_T_..ctor.BQ7SXSX0RJJGA8DO29J5OPPQ6.md 'DevElf\.RoundRobinNumberGenerator\\.RoundRobinNumberGenerator\(T, T\)') | Initializes a new instance of the [RoundRobinNumberGenerator<T>](RoundRobinNumberGenerator_T_.md 'DevElf\.RoundRobinNumberGenerator\') class\. | + +| Methods | | +| :--- | :--- | +| [NextValue\(\)](RoundRobinNumberGenerator_T_.NextValue().md 'DevElf\.RoundRobinNumberGenerator\\.NextValue\(\)') | Gets the next value in the round\-robin sequence\. | diff --git a/docs/api/DevElf/SerializableExceptionWrapper..ctor.LZH9UCLTN28N35I70OCL3GM65.md b/docs/api/DevElf/SerializableExceptionWrapper..ctor.LZH9UCLTN28N35I70OCL3GM65.md new file mode 100644 index 0000000..75c696d --- /dev/null +++ b/docs/api/DevElf/SerializableExceptionWrapper..ctor.LZH9UCLTN28N35I70OCL3GM65.md @@ -0,0 +1,22 @@ +#### [DevElf](README.md 'README') +### [DevElf](DevElf.md 'DevElf').[SerializableExceptionWrapper](SerializableExceptionWrapper.md 'DevElf\.SerializableExceptionWrapper') + +## SerializableExceptionWrapper\(Exception\) Constructor + +Initializes a new instance of the [SerializableExceptionWrapper](SerializableExceptionWrapper.md 'DevElf\.SerializableExceptionWrapper') class\. + +```csharp +public SerializableExceptionWrapper(System.Exception exception); +``` +#### Parameters + + + +`exception` [System\.Exception](https://learn.microsoft.com/en-us/dotnet/api/system.exception 'System\.Exception') + +The exception to wrap\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +Thrown if [exception](SerializableExceptionWrapper..ctor.LZH9UCLTN28N35I70OCL3GM65.md#DevElf.SerializableExceptionWrapper.SerializableExceptionWrapper(System.Exception).exception 'DevElf\.SerializableExceptionWrapper\.SerializableExceptionWrapper\(System\.Exception\)\.exception') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. \ No newline at end of file diff --git a/docs/api/DevElf/SerializableExceptionWrapper.Data.md b/docs/api/DevElf/SerializableExceptionWrapper.Data.md new file mode 100644 index 0000000..533bc6e --- /dev/null +++ b/docs/api/DevElf/SerializableExceptionWrapper.Data.md @@ -0,0 +1,13 @@ +#### [DevElf](README.md 'README') +### [DevElf](DevElf.md 'DevElf').[SerializableExceptionWrapper](SerializableExceptionWrapper.md 'DevElf\.SerializableExceptionWrapper') + +## SerializableExceptionWrapper\.Data Property + +Gets the data associated with the exception\. + +```csharp +public System.Collections.IDictionary Data { get; } +``` + +#### Property Value +[System\.Collections\.IDictionary](https://learn.microsoft.com/en-us/dotnet/api/system.collections.idictionary 'System\.Collections\.IDictionary') \ No newline at end of file diff --git a/docs/api/DevElf/SerializableExceptionWrapper.HResult.md b/docs/api/DevElf/SerializableExceptionWrapper.HResult.md new file mode 100644 index 0000000..29bd11f --- /dev/null +++ b/docs/api/DevElf/SerializableExceptionWrapper.HResult.md @@ -0,0 +1,13 @@ +#### [DevElf](README.md 'README') +### [DevElf](DevElf.md 'DevElf').[SerializableExceptionWrapper](SerializableExceptionWrapper.md 'DevElf\.SerializableExceptionWrapper') + +## SerializableExceptionWrapper\.HResult Property + +Gets the HRESULT value for the exception\. + +```csharp +public int HResult { get; } +``` + +#### Property Value +[System\.Int32](https://learn.microsoft.com/en-us/dotnet/api/system.int32 'System\.Int32') \ No newline at end of file diff --git a/docs/api/DevElf/SerializableExceptionWrapper.HelpLink.md b/docs/api/DevElf/SerializableExceptionWrapper.HelpLink.md new file mode 100644 index 0000000..0498e5e --- /dev/null +++ b/docs/api/DevElf/SerializableExceptionWrapper.HelpLink.md @@ -0,0 +1,13 @@ +#### [DevElf](README.md 'README') +### [DevElf](DevElf.md 'DevElf').[SerializableExceptionWrapper](SerializableExceptionWrapper.md 'DevElf\.SerializableExceptionWrapper') + +## SerializableExceptionWrapper\.HelpLink Property + +Gets the help link for the exception\. + +```csharp +public string? HelpLink { get; } +``` + +#### Property Value +[System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') \ No newline at end of file diff --git a/docs/api/DevElf/SerializableExceptionWrapper.InnerException.md b/docs/api/DevElf/SerializableExceptionWrapper.InnerException.md new file mode 100644 index 0000000..7535b87 --- /dev/null +++ b/docs/api/DevElf/SerializableExceptionWrapper.InnerException.md @@ -0,0 +1,13 @@ +#### [DevElf](README.md 'README') +### [DevElf](DevElf.md 'DevElf').[SerializableExceptionWrapper](SerializableExceptionWrapper.md 'DevElf\.SerializableExceptionWrapper') + +## SerializableExceptionWrapper\.InnerException Property + +Gets the wrapped inner exception, if any\. + +```csharp +public DevElf.SerializableExceptionWrapper? InnerException { get; } +``` + +#### Property Value +[SerializableExceptionWrapper](SerializableExceptionWrapper.md 'DevElf\.SerializableExceptionWrapper') \ No newline at end of file diff --git a/docs/api/DevElf/SerializableExceptionWrapper.Message.md b/docs/api/DevElf/SerializableExceptionWrapper.Message.md new file mode 100644 index 0000000..3b1d166 --- /dev/null +++ b/docs/api/DevElf/SerializableExceptionWrapper.Message.md @@ -0,0 +1,13 @@ +#### [DevElf](README.md 'README') +### [DevElf](DevElf.md 'DevElf').[SerializableExceptionWrapper](SerializableExceptionWrapper.md 'DevElf\.SerializableExceptionWrapper') + +## SerializableExceptionWrapper\.Message Property + +Gets the message describing the exception\. + +```csharp +public string Message { get; } +``` + +#### Property Value +[System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') \ No newline at end of file diff --git a/docs/api/DevElf/SerializableExceptionWrapper.Source.md b/docs/api/DevElf/SerializableExceptionWrapper.Source.md new file mode 100644 index 0000000..3ea7a8d --- /dev/null +++ b/docs/api/DevElf/SerializableExceptionWrapper.Source.md @@ -0,0 +1,13 @@ +#### [DevElf](README.md 'README') +### [DevElf](DevElf.md 'DevElf').[SerializableExceptionWrapper](SerializableExceptionWrapper.md 'DevElf\.SerializableExceptionWrapper') + +## SerializableExceptionWrapper\.Source Property + +Gets the source of the exception\. + +```csharp +public string? Source { get; } +``` + +#### Property Value +[System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') \ No newline at end of file diff --git a/docs/api/DevElf/SerializableExceptionWrapper.StackTrace.md b/docs/api/DevElf/SerializableExceptionWrapper.StackTrace.md new file mode 100644 index 0000000..be15f3f --- /dev/null +++ b/docs/api/DevElf/SerializableExceptionWrapper.StackTrace.md @@ -0,0 +1,13 @@ +#### [DevElf](README.md 'README') +### [DevElf](DevElf.md 'DevElf').[SerializableExceptionWrapper](SerializableExceptionWrapper.md 'DevElf\.SerializableExceptionWrapper') + +## SerializableExceptionWrapper\.StackTrace Property + +Gets the stack trace for the exception\. + +```csharp +public string? StackTrace { get; } +``` + +#### Property Value +[System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') \ No newline at end of file diff --git a/docs/api/DevElf/SerializableExceptionWrapper.ToString().md b/docs/api/DevElf/SerializableExceptionWrapper.ToString().md new file mode 100644 index 0000000..d62ee8c --- /dev/null +++ b/docs/api/DevElf/SerializableExceptionWrapper.ToString().md @@ -0,0 +1,14 @@ +#### [DevElf](README.md 'README') +### [DevElf](DevElf.md 'DevElf').[SerializableExceptionWrapper](SerializableExceptionWrapper.md 'DevElf\.SerializableExceptionWrapper') + +## SerializableExceptionWrapper\.ToString\(\) Method + +Returns a string representation of the wrapped exception, serialized as JSON if possible\. + +```csharp +public override string ToString(); +``` + +#### Returns +[System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') +A JSON string if serialization succeeds; otherwise, the original [System\.Exception\.ToString](https://learn.microsoft.com/en-us/dotnet/api/system.exception.tostring 'System\.Exception\.ToString') value\. \ No newline at end of file diff --git a/docs/api/DevElf/SerializableExceptionWrapper.md b/docs/api/DevElf/SerializableExceptionWrapper.md new file mode 100644 index 0000000..551174d --- /dev/null +++ b/docs/api/DevElf/SerializableExceptionWrapper.md @@ -0,0 +1,30 @@ +#### [DevElf](README.md 'README') +### [DevElf](DevElf.md 'DevElf') + +## SerializableExceptionWrapper Class + +Wraps an [System\.Exception](https://learn.microsoft.com/en-us/dotnet/api/system.exception 'System\.Exception') for serialization, including its properties and inner exception\. + +```csharp +public class SerializableExceptionWrapper +``` + +Inheritance [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') 🡒 SerializableExceptionWrapper + +| Constructors | | +| :--- | :--- | +| [SerializableExceptionWrapper\(Exception\)](SerializableExceptionWrapper..ctor.LZH9UCLTN28N35I70OCL3GM65.md 'DevElf\.SerializableExceptionWrapper\.SerializableExceptionWrapper\(System\.Exception\)') | Initializes a new instance of the [SerializableExceptionWrapper](SerializableExceptionWrapper.md 'DevElf\.SerializableExceptionWrapper') class\. | + +| Properties | | +| :--- | :--- | +| [Data](SerializableExceptionWrapper.Data.md 'DevElf\.SerializableExceptionWrapper\.Data') | Gets the data associated with the exception\. | +| [HelpLink](SerializableExceptionWrapper.HelpLink.md 'DevElf\.SerializableExceptionWrapper\.HelpLink') | Gets the help link for the exception\. | +| [HResult](SerializableExceptionWrapper.HResult.md 'DevElf\.SerializableExceptionWrapper\.HResult') | Gets the HRESULT value for the exception\. | +| [InnerException](SerializableExceptionWrapper.InnerException.md 'DevElf\.SerializableExceptionWrapper\.InnerException') | Gets the wrapped inner exception, if any\. | +| [Message](SerializableExceptionWrapper.Message.md 'DevElf\.SerializableExceptionWrapper\.Message') | Gets the message describing the exception\. | +| [Source](SerializableExceptionWrapper.Source.md 'DevElf\.SerializableExceptionWrapper\.Source') | Gets the source of the exception\. | +| [StackTrace](SerializableExceptionWrapper.StackTrace.md 'DevElf\.SerializableExceptionWrapper\.StackTrace') | Gets the stack trace for the exception\. | + +| Methods | | +| :--- | :--- | +| [ToString\(\)](SerializableExceptionWrapper.ToString().md 'DevElf\.SerializableExceptionWrapper\.ToString\(\)') | Returns a string representation of the wrapped exception, serialized as JSON if possible\. | diff --git a/src/DevElf.Logging/LogMessageScope.cs b/src/DevElf.Logging/LogMessageScope.cs index 4198495..890c38f 100644 --- a/src/DevElf.Logging/LogMessageScope.cs +++ b/src/DevElf.Logging/LogMessageScope.cs @@ -27,7 +27,7 @@ internal sealed partial class LogMessageScope : IDisposable, ILogMessageScope private readonly ConcurrentDictionary _properties = new(StringComparer.OrdinalIgnoreCase); #pragma warning disable CA2213 // Disposable fields should be disposed => By design. We don't own the parent scope. - private readonly LogMessageScope? _parent; + private readonly LogMessageScope? parent; #pragma warning restore CA2213 // Disposable fields should be disposed private readonly ILogger _logger; @@ -57,12 +57,12 @@ public LogMessageScope( logLevel.ThrowIfNotDefined(); message.ThrowIfNullOrWhiteSpace(); - _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - _logLevel = logLevel; - _eventId = eventId; - _message = message; + this._logger = logger ?? throw new ArgumentNullException(nameof(logger)); + this._logLevel = logLevel; + this._eventId = eventId; + this._message = message; - _parent = AsyncLocalLogMessageScopeStack.Peek(); + this.parent = AsyncLocalLogMessageScopeStack.Peek(); AsyncLocalLogMessageScopeStack.Push(this); } @@ -75,10 +75,10 @@ public LogMessageScope( /// Returns the provided to enable fluent assignment. public T SetProperty(string key, T value) { - ObjectDisposedException.ThrowIf(_disposed, this); + ObjectDisposedException.ThrowIf(this._disposed, this); key.ThrowIfNullOrWhiteSpace(); - _properties[key] = value; + this._properties[key] = value; return value; } @@ -92,10 +92,10 @@ public T SetProperty(string key, T value) /// public void SetException(Exception exception, bool setProperty = false) { - ObjectDisposedException.ThrowIf(_disposed, this); + ObjectDisposedException.ThrowIf(this._disposed, this); exception.ThrowIfNull(); - _exception = setProperty ? SetProperty(nameof(Exception), exception) : exception; + this._exception = setProperty ? SetProperty(nameof(Exception), exception) : exception; } /// @@ -104,10 +104,10 @@ public void SetException(Exception exception, bool setProperty = false) /// The new log level. public void ChangeLogLevel(LogLevel logLevel) { - ObjectDisposedException.ThrowIf(_disposed, this); + ObjectDisposedException.ThrowIf(this._disposed, this); logLevel.ThrowIfNotDefined(); - _logLevel = logLevel; + this._logLevel = logLevel; } /// @@ -116,9 +116,9 @@ public void ChangeLogLevel(LogLevel logLevel) /// The new event ID. public void ChangeEventId(EventId eventId) { - ObjectDisposedException.ThrowIf(_disposed, this); + ObjectDisposedException.ThrowIf(this._disposed, this); - _eventId = eventId; + this._eventId = eventId; } /// @@ -127,10 +127,10 @@ public void ChangeEventId(EventId eventId) /// The new message. public void ChangeMessage(string message) { - ObjectDisposedException.ThrowIf(_disposed, this); + ObjectDisposedException.ThrowIf(this._disposed, this); message.ThrowIfNullOrWhiteSpace(); - _message = message; + this._message = message; } /// @@ -140,7 +140,7 @@ public void ChangeMessage(string message) /// public void Dispose() { - if (_disposed) + if (this._disposed) { return; } @@ -160,7 +160,7 @@ public void Dispose() Log(GetAllProperties()); // Finally mark as disposed - _disposed = true; + this._disposed = true; } /// @@ -168,9 +168,9 @@ public void Dispose() /// private Dictionary GetAllProperties() { - Dictionary parentProperties = _parent?.GetAllProperties() ?? new(StringComparer.OrdinalIgnoreCase); + Dictionary parentProperties = this.parent?.GetAllProperties() ?? new(StringComparer.OrdinalIgnoreCase); - foreach (KeyValuePair property in _properties) + foreach (KeyValuePair property in this._properties) { parentProperties[property.Key] = property.Value; } @@ -180,13 +180,13 @@ public void Dispose() private void Log(IReadOnlyDictionary properties) { - if (_logger.IsEnabled(_logLevel)) + if (this._logger.IsEnabled(this._logLevel)) { - using (_logger.BeginScope(properties)) + using (this._logger.BeginScope(properties)) { #pragma warning disable CA1848 // Use the LoggerMessage delegates #pragma warning disable CA2254 // Template should be a static expression - _logger.Log(_logLevel, _eventId, _exception, _message); + this._logger.Log(this._logLevel, this._eventId, this._exception, this._message); #pragma warning restore CA2254 // Template should be a static expression #pragma warning restore CA1848 // Use the LoggerMessage delegates } diff --git a/src/DevElf/FrozenTimeProvider.cs b/src/DevElf/FrozenTimeProvider.cs index 302fb41..35f02c9 100644 --- a/src/DevElf/FrozenTimeProvider.cs +++ b/src/DevElf/FrozenTimeProvider.cs @@ -8,7 +8,7 @@ namespace DevElf; /// public sealed class FrozenTimeProvider : TimeProvider { - private readonly DateTimeOffset _utcNow; + private readonly DateTimeOffset utcNow; /// /// Creates a new instance that will always return the provided instant in UTC. @@ -16,7 +16,7 @@ public sealed class FrozenTimeProvider : TimeProvider /// /// The instant to freeze. public FrozenTimeProvider(DateTimeOffset now) - => this._utcNow = now.ToUniversalTime(); + => this.utcNow = now.ToUniversalTime(); /// /// Creates a new instance that is frozen to the current value of the @@ -28,12 +28,12 @@ public FrozenTimeProvider(TimeProvider timeProvider) { timeProvider.ThrowIfNull(); - this._utcNow = timeProvider.GetUtcNow(); + this.utcNow = timeProvider.GetUtcNow(); } /// /// Returns the frozen instant as a UTC . /// /// The frozen UTC instant. - public override DateTimeOffset GetUtcNow() => this._utcNow; + public override DateTimeOffset GetUtcNow() => this.utcNow; } diff --git a/src/DevElf/IRoundRobinGenerator.cs b/src/DevElf/IRoundRobinGenerator.cs new file mode 100644 index 0000000..ebec8b8 --- /dev/null +++ b/src/DevElf/IRoundRobinGenerator.cs @@ -0,0 +1,15 @@ +namespace DevElf; + +/// +/// Defines a generator that produces values in a round-robin sequence. +/// +/// A type that implements . +public interface IRoundRobinGenerator + where T : IComparable +{ + /// + /// Gets the next value in the round-robin sequence. + /// + /// The next value in the sequence. + T NextValue(); +} diff --git a/src/DevElf/RoundRobinGeneratorBase.cs b/src/DevElf/RoundRobinGeneratorBase.cs new file mode 100644 index 0000000..b09e6f0 --- /dev/null +++ b/src/DevElf/RoundRobinGeneratorBase.cs @@ -0,0 +1,67 @@ +using DevElf.ArgumentValidation; + +namespace DevElf; + +/// +/// Provides a base implementation for round-robin generators using a comparer. +/// +/// A type implementing . +public abstract class RoundRobinGeneratorBase : IRoundRobinGenerator + where T : IComparable +{ + private readonly IComparer comparer; + + private readonly Lock syncRoot = new(); + private readonly T start; + private readonly T end; + + private T previous; + + /// + /// Initializes a new instance of the class. + /// + /// The starting value of the sequence. + /// The ending value of the sequence. + /// The comparer to use for value comparison. If , the default comparer is used. + /// Thrown if is greater than . + protected RoundRobinGeneratorBase(T start, T end, IComparer? comparer = null) + { + start.ThrowIfGreaterThan(end); + + this.comparer = comparer ?? Comparer.Default; + this.start = start; + this.end = end; + this.previous = end; + } + + /// + /// Gets the next value in the round-robin sequence. + /// + /// The next value in the sequence. + public T NextValue() + { + lock (this.syncRoot) + { + if (this.comparer.Compare(this.start, this.end) == 0) + { + return this.start; + } + + if (this.comparer.Compare(this.previous, this.end) >= 0) + { + this.previous = this.start; + + return this.previous; + } + + return Increment(ref this.previous); + } + } + + /// + /// Increments the value for the next round-robin step. + /// + /// The value to increment. + /// The incremented value. + protected abstract T Increment(ref T value); +} diff --git a/src/DevElf/RoundRobinNumberGenerator.cs b/src/DevElf/RoundRobinNumberGenerator.cs new file mode 100644 index 0000000..6f9144f --- /dev/null +++ b/src/DevElf/RoundRobinNumberGenerator.cs @@ -0,0 +1,57 @@ +using System.Numerics; +using DevElf.ArgumentValidation; + +namespace DevElf; + +/// +/// Generates numbers in a round-robin fashion between a start and end value. +/// +/// A numeric type implementing and . +public class RoundRobinNumberGenerator : IRoundRobinGenerator + where T : INumber, IComparable +{ + private readonly Lock syncRoot = new(); + private readonly T start; + private readonly T end; + + private T last; + + /// + /// Initializes a new instance of the class. + /// + /// The starting value of the sequence. + /// The ending value of the sequence. + /// Thrown if is greater than . + public RoundRobinNumberGenerator(T start, T end) + { + start.ThrowIfGreaterThan(end); + + this.start = start; + this.end = end; + this.last = end; + } + + /// + /// Gets the next value in the round-robin sequence. + /// + /// The next value in the sequence. + public T NextValue() + { + lock (this.syncRoot) + { + if (this.start == this.end) + { + return this.start; + } + + if (this.last >= this.end) + { + this.last = this.start; + + return this.last; + } + + return ++this.last; + } + } +} diff --git a/src/DevElf/SerializableExceptionWrapper.cs b/src/DevElf/SerializableExceptionWrapper.cs new file mode 100644 index 0000000..e1af01d --- /dev/null +++ b/src/DevElf/SerializableExceptionWrapper.cs @@ -0,0 +1,87 @@ +using System.Collections; +using System.Text.Json; +using DevElf.ArgumentValidation; + +namespace DevElf; + +/// +/// Wraps an for serialization, including its properties and inner exception. +/// +public class SerializableExceptionWrapper +{ + private readonly string toString; + + /// + /// Initializes a new instance of the class. + /// + /// The exception to wrap. + /// + /// Thrown if is . + /// + public SerializableExceptionWrapper(Exception exception) + { + exception.ThrowIfNull(); + + Data = exception.Data; + HelpLink = exception.HelpLink; + HResult = exception.HResult; + InnerException = exception.InnerException is null ? null : new SerializableExceptionWrapper(exception.InnerException); + Message = exception.Message; + Source = exception.Source; + StackTrace = exception.StackTrace; + this.toString = exception.ToString(); + } + + /// + /// Gets the data associated with the exception. + /// + public IDictionary Data { get; } + + /// + /// Gets the help link for the exception. + /// + public string? HelpLink { get; } + + /// + /// Gets the HRESULT value for the exception. + /// + public int HResult { get; } + + /// + /// Gets the wrapped inner exception, if any. + /// + public SerializableExceptionWrapper? InnerException { get; } + + /// + /// Gets the message describing the exception. + /// + public string Message { get; } + + /// + /// Gets the source of the exception. + /// + public string? Source { get; } + + /// + /// Gets the stack trace for the exception. + /// + public string? StackTrace { get; } + + /// + /// Returns a string representation of the wrapped exception, serialized as JSON if possible. + /// + /// + /// A JSON string if serialization succeeds; otherwise, the original value. + /// + public override string ToString() + { + try + { + return JsonSerializer.Serialize(this); + } + catch (Exception) + { + return this.toString; + } + } +} diff --git a/tests/DevElf.Logging.Tests/LogMessageScopeManualTests.cs b/tests/DevElf.Logging.Tests/LogMessageScopeManualTests.cs index 9762252..02a1f89 100644 --- a/tests/DevElf.Logging.Tests/LogMessageScopeManualTests.cs +++ b/tests/DevElf.Logging.Tests/LogMessageScopeManualTests.cs @@ -32,8 +32,8 @@ public void Test() public class X { - private readonly ILogMessageScopeAccessor _logMessageScopeAccessor; - private readonly ILogger _logger; + private readonly ILogMessageScopeAccessor logMessageScopeAccessor; + private readonly ILogger logger; public X(ILogMessageScopeAccessor logMessageScopeAccessor, ILogger logger) { @@ -42,16 +42,16 @@ public X(ILogMessageScopeAccessor logMessageScopeAccessor, ILogger logger) _ = scope.SetProperty("XKey", "XValue"); } - _logMessageScopeAccessor = logMessageScopeAccessor; - _logger = logger; + this.logMessageScopeAccessor = logMessageScopeAccessor; + this.logger = logger; } public void Y() { - using var scope = _logger.BeginMessageScope(LogLevel.Error, "Error message from Y"); + using var scope = this.logger.BeginMessageScope(LogLevel.Error, "Error message from Y"); _ = scope.SetProperty("YKey", "YValue"); } - public void Z() => _logMessageScopeAccessor.Current?.SetProperty("ZKey", "ZValue"); + public void Z() => this.logMessageScopeAccessor.Current?.SetProperty("ZKey", "ZValue"); } } diff --git a/tests/DevElf.Tests/RoundRobinGeneratorBaseTests.cs b/tests/DevElf.Tests/RoundRobinGeneratorBaseTests.cs new file mode 100644 index 0000000..665e579 --- /dev/null +++ b/tests/DevElf.Tests/RoundRobinGeneratorBaseTests.cs @@ -0,0 +1,57 @@ +using AwesomeAssertions; + +namespace DevElf.Tests; + +[TestClass] +public class RoundRobinGeneratorBaseTests +{ + [TestMethod] + public void NextValue_returns_start_when_start_equals_end() + { + // Arrange + var sut = new IntRoundRobinGenerator(7, 7); + + // Act + int result = sut.NextValue(); + + // Assert + _ = result.Should().Be(7); + } + + [TestMethod] + public void NextValue_cycles_through_range_and_wraps_to_start() + { + // Arrange + var sut = new IntRoundRobinGenerator(2, 4); + + // Act + int first = sut.NextValue(); + int second = sut.NextValue(); + int third = sut.NextValue(); + int fourth = sut.NextValue(); + int fifth = sut.NextValue(); + + // Assert + _ = first.Should().Be(2); + _ = second.Should().Be(3); + _ = third.Should().Be(4); + _ = fourth.Should().Be(2); + _ = fifth.Should().Be(3); + } + + [TestMethod] + public void Constructor_throws_when_start_greater_than_end() + { + // Arrange + // Act + var act = () => new IntRoundRobinGenerator(5, 2); + + // Assert + _ = act.Should().Throw(); + } + + private class IntRoundRobinGenerator(int start, int end, IComparer? comparer = null) : RoundRobinGeneratorBase(start, end, comparer) + { + protected override int Increment(ref int value) => ++value; + } +} diff --git a/tests/DevElf.Tests/RoundRobinNumberGeneratorTests.cs b/tests/DevElf.Tests/RoundRobinNumberGeneratorTests.cs new file mode 100644 index 0000000..383117b --- /dev/null +++ b/tests/DevElf.Tests/RoundRobinNumberGeneratorTests.cs @@ -0,0 +1,53 @@ +using System.Numerics; +using AwesomeAssertions; + +namespace DevElf.Tests; + +[TestClass] +public class RoundRobinNumberGeneratorTests +{ + [TestMethod] + public void NextValue_returns_start_when_start_equals_end() + { + // Arrange + var sut = new RoundRobinNumberGenerator(5, 5); + + // Act + int result = sut.NextValue(); + + // Assert + _ = result.Should().Be(5); + } + + [TestMethod] + public void NextValue_cycles_through_range_and_wraps_to_start() + { + // Arrange + var sut = new RoundRobinNumberGenerator(1, 3); + + // Act + int first = sut.NextValue(); + int second = sut.NextValue(); + int third = sut.NextValue(); + int fourth = sut.NextValue(); + int fifth = sut.NextValue(); + + // Assert + _ = first.Should().Be(1); + _ = second.Should().Be(2); + _ = third.Should().Be(3); + _ = fourth.Should().Be(1); + _ = fifth.Should().Be(2); + } + + [TestMethod] + public void Constructor_throws_when_start_greater_than_end() + { + // Arrange + // Act + var act = () => new RoundRobinNumberGenerator(10, 5); + + // Assert + _ = act.Should().Throw(); + } +} diff --git a/tests/DevElf.Tests/SerializableExceptionWrapperTests.cs b/tests/DevElf.Tests/SerializableExceptionWrapperTests.cs new file mode 100644 index 0000000..2d237f6 --- /dev/null +++ b/tests/DevElf.Tests/SerializableExceptionWrapperTests.cs @@ -0,0 +1,79 @@ +using AwesomeAssertions; + +namespace DevElf.Tests; + +[TestClass] +public class SerializableExceptionWrapperTests +{ + [TestMethod] + public void Constructor_wraps_exception_properties_correctly() + { + // Arrange + var ex = new InvalidOperationException("Test message") + { + HelpLink = "http://help", + Source = "TestSource", + HResult = 42 + }; + ex.Data["Key"] = "Value"; + + try + { + throw ex; + } + catch (Exception caughtEx) + { + // Act + var wrapper = new SerializableExceptionWrapper(caughtEx); + + // Assert + _ = wrapper.Message.Should().Be(ex.Message); + _ = wrapper.HelpLink.Should().Be(ex.HelpLink); + _ = wrapper.HResult.Should().Be(ex.HResult); + _ = wrapper.Source.Should().Be(ex.Source); + _ = wrapper.StackTrace.Should().NotBeNull(); + _ = wrapper.Data["Key"].Should().Be("Value"); + } + } + + [TestMethod] + public void Constructor_wraps_inner_exception() + { + // Arrange + var inner = new Exception("Inner"); + var ex = new Exception("Outer", inner); + + // Act + var wrapper = new SerializableExceptionWrapper(ex); + + // Assert + _ = wrapper.InnerException.Should().NotBeNull(); + _ = wrapper.InnerException!.Message.Should().Be("Inner"); + } + + [TestMethod] + public void ToString_returns_json_serialized_string() + { + // Arrange + var ex = new Exception("Test"); + var wrapper = new SerializableExceptionWrapper(ex); + + // Act + string result = wrapper.ToString(); + + // Assert + _ = result.Should().Contain("Test"); + _ = result.Should().Contain("Message"); + } + + [TestMethod] + public void Constructor_throws_on_null_exception() + { + // Arrange + // Act + var act = () => new SerializableExceptionWrapper(null!); + + // Assert + _ = act.Should().Throw(); + } +} From 8adc4c91fb1ecebf902dc3cce75de3af168a7c40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Luis=20Barreda=20G=C3=BCere=C3=B1a?= Date: Sat, 11 Oct 2025 02:34:09 -0700 Subject: [PATCH 3/6] feat: add EnterCatch class for catch block filters Introduced the `EnterCatch` class in the `DevElf` namespace, providing utility methods for executing actions in `catch` block filter conditions. Added the following methods: - `Never(Action)`: Executes an action and prevents the `catch` block from being entered. - `AfterAction(Action)`: Executes an action and ensures the `catch` block is entered. - `AfterActionIf(Action, Func)`: Executes an action and conditionally determines whether the `catch` block is entered. Updated `DevElf.md` with detailed documentation for the `EnterCatch` class and its methods, including examples and remarks. Highlighted limitations with async code and referenced Stephen Cleary's blog post on exception logging patterns. Added comprehensive unit tests in `EnterCatchTests.cs` to verify the behavior of all methods, including null argument validation, exception context preservation, and conditional handling logic. --- docs/api/DevElf/DevElf.md | 1 + ...h.AfterAction.BJVVNWQM01735O03T92W9JJ32.md | 47 +++ ...AfterActionIf.RF5K4LN2HEZ7HARW4VD30YTB2.md | 56 ++++ ...erCatch.Never.TDCCB41YVHYEQW8AZPJI45OC5.md | 46 +++ docs/api/DevElf/EnterCatch.md | 51 ++++ src/DevElf/EnterCatch.cs | 167 ++++++++++ tests/DevElf.Tests/EnterCatchTests.cs | 286 ++++++++++++++++++ 7 files changed, 654 insertions(+) create mode 100644 docs/api/DevElf/EnterCatch.AfterAction.BJVVNWQM01735O03T92W9JJ32.md create mode 100644 docs/api/DevElf/EnterCatch.AfterActionIf.RF5K4LN2HEZ7HARW4VD30YTB2.md create mode 100644 docs/api/DevElf/EnterCatch.Never.TDCCB41YVHYEQW8AZPJI45OC5.md create mode 100644 docs/api/DevElf/EnterCatch.md create mode 100644 src/DevElf/EnterCatch.cs create mode 100644 tests/DevElf.Tests/EnterCatchTests.cs diff --git a/docs/api/DevElf/DevElf.md b/docs/api/DevElf/DevElf.md index 5dfe0b3..e5c933e 100644 --- a/docs/api/DevElf/DevElf.md +++ b/docs/api/DevElf/DevElf.md @@ -4,6 +4,7 @@ | Classes | | | :--- | :--- | +| [EnterCatch](EnterCatch.md 'DevElf\.EnterCatch') | Provides helper methods for executing actions in catch block filter conditions\. Allows running actions \(such as logging\) while preserving the original exception context and controlling whether to enter the catch block\. | | [FrozenTimeProvider](FrozenTimeProvider.md 'DevElf\.FrozenTimeProvider') | A [System\.TimeProvider](https://learn.microsoft.com/en-us/dotnet/api/system.timeprovider 'System\.TimeProvider') that always returns a fixed point in time\. Useful for tests and deterministic time\-dependent logic\. | | [RoundRobinGeneratorBase<T>](RoundRobinGeneratorBase_T_.md 'DevElf\.RoundRobinGeneratorBase\') | Provides a base implementation for round\-robin generators using a comparer\. | | [RoundRobinNumberGenerator<T>](RoundRobinNumberGenerator_T_.md 'DevElf\.RoundRobinNumberGenerator\') | Generates numbers in a round\-robin fashion between a start and end value\. | diff --git a/docs/api/DevElf/EnterCatch.AfterAction.BJVVNWQM01735O03T92W9JJ32.md b/docs/api/DevElf/EnterCatch.AfterAction.BJVVNWQM01735O03T92W9JJ32.md new file mode 100644 index 0000000..1fcd656 --- /dev/null +++ b/docs/api/DevElf/EnterCatch.AfterAction.BJVVNWQM01735O03T92W9JJ32.md @@ -0,0 +1,47 @@ +#### [DevElf](README.md 'README') +### [DevElf](DevElf.md 'DevElf').[EnterCatch](EnterCatch.md 'DevElf\.EnterCatch') + +## EnterCatch\.AfterAction\(Action\) Method + +Executes an action and always returns [true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool'), causing the +catch block to be entered\. + +```csharp +public static bool AfterAction(System.Action action); +``` +#### Parameters + + + +`action` [System\.Action](https://learn.microsoft.com/en-us/dotnet/api/system.action 'System\.Action') + +The action to execute in the filter condition\. + +#### Returns +[System\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean') +Always returns [true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool'), causing the catch block to be +entered\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +If [action](EnterCatch.AfterAction.BJVVNWQM01735O03T92W9JJ32.md#DevElf.EnterCatch.AfterAction(System.Action).action 'DevElf\.EnterCatch\.AfterAction\(System\.Action\)\.action') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + +### Example + +```csharp +try +{ + // Code that might throw +} +catch (Exception ex) when (EnterCatch.AfterAction(() => logger.LogError(ex))) +{ + // Handle the exception + return fallbackValue; +} +``` + +### Remarks +This method allows you to execute an action \(such as logging\) in the +exception filter before entering the catch block, preserving the original +exception context\. \ No newline at end of file diff --git a/docs/api/DevElf/EnterCatch.AfterActionIf.RF5K4LN2HEZ7HARW4VD30YTB2.md b/docs/api/DevElf/EnterCatch.AfterActionIf.RF5K4LN2HEZ7HARW4VD30YTB2.md new file mode 100644 index 0000000..6d5bb8f --- /dev/null +++ b/docs/api/DevElf/EnterCatch.AfterActionIf.RF5K4LN2HEZ7HARW4VD30YTB2.md @@ -0,0 +1,56 @@ +#### [DevElf](README.md 'README') +### [DevElf](DevElf.md 'DevElf').[EnterCatch](EnterCatch.md 'DevElf\.EnterCatch') + +## EnterCatch\.AfterActionIf\(Action, Func\\) Method + +Executes an action and then evaluates a condition to determine whether the +catch block should be entered\. + +```csharp +public static bool AfterActionIf(System.Action action, System.Func condition); +``` +#### Parameters + + + +`action` [System\.Action](https://learn.microsoft.com/en-us/dotnet/api/system.action 'System\.Action') + +The action to execute in the filter condition\. + + + +`condition` [System\.Func<](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')[System\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean')[>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1') + +The function that determines whether to enter the catch block\. + +#### Returns +[System\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean') +The result of evaluating [condition](EnterCatch.AfterActionIf.RF5K4LN2HEZ7HARW4VD30YTB2.md#DevElf.EnterCatch.AfterActionIf(System.Action,System.Func_bool_).condition 'DevElf\.EnterCatch\.AfterActionIf\(System\.Action, System\.Func\\)\.condition'), which determines +whether the catch block is entered\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +If [action](EnterCatch.AfterActionIf.RF5K4LN2HEZ7HARW4VD30YTB2.md#DevElf.EnterCatch.AfterActionIf(System.Action,System.Func_bool_).action 'DevElf\.EnterCatch\.AfterActionIf\(System\.Action, System\.Func\\)\.action') or [condition](EnterCatch.AfterActionIf.RF5K4LN2HEZ7HARW4VD30YTB2.md#DevElf.EnterCatch.AfterActionIf(System.Action,System.Func_bool_).condition 'DevElf\.EnterCatch\.AfterActionIf\(System\.Action, System\.Func\\)\.condition') is +[null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + +### Example + +```csharp +try +{ + // Code that might throw +} +catch (Exception ex) when (EnterCatch.AfterActionIf( + () => logger.LogError(ex), + () => retryCount < maxRetries)) +{ + // Only handle if retryCount is less than maxRetries + retryCount++; +} +``` + +### Remarks +This method allows you to execute an action \(such as logging\) and then +conditionally decide whether to handle the exception based on runtime +conditions\. \ No newline at end of file diff --git a/docs/api/DevElf/EnterCatch.Never.TDCCB41YVHYEQW8AZPJI45OC5.md b/docs/api/DevElf/EnterCatch.Never.TDCCB41YVHYEQW8AZPJI45OC5.md new file mode 100644 index 0000000..47a1946 --- /dev/null +++ b/docs/api/DevElf/EnterCatch.Never.TDCCB41YVHYEQW8AZPJI45OC5.md @@ -0,0 +1,46 @@ +#### [DevElf](README.md 'README') +### [DevElf](DevElf.md 'DevElf').[EnterCatch](EnterCatch.md 'DevElf\.EnterCatch') + +## EnterCatch\.Never\(Action\) Method + +Executes an action and always returns [false](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool'), preventing +the catch block from being entered\. + +```csharp +public static bool Never(System.Action action); +``` +#### Parameters + + + +`action` [System\.Action](https://learn.microsoft.com/en-us/dotnet/api/system.action 'System\.Action') + +The action to execute in the filter condition\. + +#### Returns +[System\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean') +Always returns [false](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool'), causing the exception to continue +propagating\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +If [action](EnterCatch.Never.TDCCB41YVHYEQW8AZPJI45OC5.md#DevElf.EnterCatch.Never(System.Action).action 'DevElf\.EnterCatch\.Never\(System\.Action\)\.action') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + +### Example + +```csharp +try +{ + // Code that might throw +} +catch (Exception ex) when (EnterCatch.Never(() => logger.LogWarning(ex))) +{ + // This block will never execute +} +``` + +### Remarks +This method is useful when you want to perform an action \(such as logging\) +in the exception filter but do not want to handle the exception\. The +exception will continue to propagate up the call stack\. \ No newline at end of file diff --git a/docs/api/DevElf/EnterCatch.md b/docs/api/DevElf/EnterCatch.md new file mode 100644 index 0000000..ad0f360 --- /dev/null +++ b/docs/api/DevElf/EnterCatch.md @@ -0,0 +1,51 @@ +#### [DevElf](README.md 'README') +### [DevElf](DevElf.md 'DevElf') + +## EnterCatch Class + +Provides helper methods for executing actions in catch block filter conditions\. +Allows running actions \(such as logging\) while preserving the original exception +context and controlling whether to enter the catch block\. + +```csharp +public static class EnterCatch +``` + +Inheritance [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') 🡒 EnterCatch + +### Example + +```csharp +try +{ + // Code that might throw +} +catch (Exception ex) when (EnterCatch.AfterAction(() => logger.LogError(ex))) +{ + // Handle exception with full context preserved +} +``` + +### Remarks + +These methods are designed to be used in catch block `when` clauses to +execute side-effect actions (typically logging) at the point where the exception +occurs, before the stack unwinds further. The return value determines whether +the catch block should be entered. + +Important: These methods do not work well with async code. + When an exception is thrown in an async method, it is caught by the async + state machine and re-thrown at the point of the `await`. This causes + the exception filter to run at the await location rather than where the + exception was originally thrown, losing the original exception context and + stack trace information that these methods are designed to preserve. + +This implementation is based on the concept described by Stephen Cleary in +"A New Pattern for Exception Logging": +https://blog.stephencleary.com/2020/06/a-new-pattern-for-exception-logging.html + +| Methods | | +| :--- | :--- | +| [AfterAction\(Action\)](EnterCatch.AfterAction.BJVVNWQM01735O03T92W9JJ32.md 'DevElf\.EnterCatch\.AfterAction\(System\.Action\)') | Executes an action and always returns [true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool'), causing the catch block to be entered\. | +| [AfterActionIf\(Action, Func<bool>\)](EnterCatch.AfterActionIf.RF5K4LN2HEZ7HARW4VD30YTB2.md 'DevElf\.EnterCatch\.AfterActionIf\(System\.Action, System\.Func\\)') | Executes an action and then evaluates a condition to determine whether the catch block should be entered\. | +| [Never\(Action\)](EnterCatch.Never.TDCCB41YVHYEQW8AZPJI45OC5.md 'DevElf\.EnterCatch\.Never\(System\.Action\)') | Executes an action and always returns [false](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool'), preventing the catch block from being entered\. | diff --git a/src/DevElf/EnterCatch.cs b/src/DevElf/EnterCatch.cs new file mode 100644 index 0000000..47ba546 --- /dev/null +++ b/src/DevElf/EnterCatch.cs @@ -0,0 +1,167 @@ +using DevElf.ArgumentValidation; + +namespace DevElf; + +/// +/// Provides helper methods for executing actions in catch block filter conditions. +/// Allows running actions (such as logging) while preserving the original exception +/// context and controlling whether to enter the catch block. +/// +/// +/// +/// These methods are designed to be used in catch block when clauses to +/// execute side-effect actions (typically logging) at the point where the exception +/// occurs, before the stack unwinds further. The return value determines whether +/// the catch block should be entered. +/// +/// +/// Important: These methods do not work well with async code. +/// When an exception is thrown in an async method, it is caught by the async +/// state machine and re-thrown at the point of the await. This causes +/// the exception filter to run at the await location rather than where the +/// exception was originally thrown, losing the original exception context and +/// stack trace information that these methods are designed to preserve. +/// +/// +/// This implementation is based on the concept described by Stephen Cleary in +/// "A New Pattern for Exception Logging": +/// https://blog.stephencleary.com/2020/06/a-new-pattern-for-exception-logging.html +/// +/// +/// +/// +/// try +/// { +/// // Code that might throw +/// } +/// catch (Exception ex) when (EnterCatch.AfterAction(() => logger.LogError(ex))) +/// { +/// // Handle exception with full context preserved +/// } +/// +/// +public static class EnterCatch +{ + /// + /// Executes an action and always returns , preventing + /// the catch block from being entered. + /// + /// The action to execute in the filter condition. + /// + /// Always returns , causing the exception to continue + /// propagating. + /// + /// + /// If is . + /// + /// + /// This method is useful when you want to perform an action (such as logging) + /// in the exception filter but do not want to handle the exception. The + /// exception will continue to propagate up the call stack. + /// + /// + /// + /// try + /// { + /// // Code that might throw + /// } + /// catch (Exception ex) when (EnterCatch.Never(() => logger.LogWarning(ex))) + /// { + /// // This block will never execute + /// } + /// + /// + public static bool Never(Action action) + { + action.ThrowIfNull(); + + action(); + + return false; + } + + /// + /// Executes an action and always returns , causing the + /// catch block to be entered. + /// + /// The action to execute in the filter condition. + /// + /// Always returns , causing the catch block to be + /// entered. + /// + /// + /// If is . + /// + /// + /// This method allows you to execute an action (such as logging) in the + /// exception filter before entering the catch block, preserving the original + /// exception context. + /// + /// + /// + /// try + /// { + /// // Code that might throw + /// } + /// catch (Exception ex) when (EnterCatch.AfterAction(() => logger.LogError(ex))) + /// { + /// // Handle the exception + /// return fallbackValue; + /// } + /// + /// + public static bool AfterAction(Action action) + { + action.ThrowIfNull(); + + action(); + + return true; + } + + /// + /// Executes an action and then evaluates a condition to determine whether the + /// catch block should be entered. + /// + /// The action to execute in the filter condition. + /// + /// The function that determines whether to enter the catch block. + /// + /// + /// The result of evaluating , which determines + /// whether the catch block is entered. + /// + /// + /// If or is + /// . + /// + /// + /// This method allows you to execute an action (such as logging) and then + /// conditionally decide whether to handle the exception based on runtime + /// conditions. + /// + /// + /// + /// try + /// { + /// // Code that might throw + /// } + /// catch (Exception ex) when (EnterCatch.AfterActionIf( + /// () => logger.LogError(ex), + /// () => retryCount < maxRetries)) + /// { + /// // Only handle if retryCount is less than maxRetries + /// retryCount++; + /// } + /// + /// + public static bool AfterActionIf(Action action, Func condition) + { + action.ThrowIfNull(); + condition.ThrowIfNull(); + + action(); + + return condition(); + } +} diff --git a/tests/DevElf.Tests/EnterCatchTests.cs b/tests/DevElf.Tests/EnterCatchTests.cs new file mode 100644 index 0000000..9382cb2 --- /dev/null +++ b/tests/DevElf.Tests/EnterCatchTests.cs @@ -0,0 +1,286 @@ +using AwesomeAssertions; + +namespace DevElf.Tests; + +[TestClass] +public class EnterCatchTests +{ + [TestMethod] + public void Never_returns_false_after_executing_action() + { + // Arrange + bool actionExecuted = false; + + // Act + bool result = EnterCatch.Never(() => actionExecuted = true); + + // Assert + _ = actionExecuted.Should().BeTrue(); + _ = result.Should().BeFalse(); + } + + [TestMethod] + public void Never_throws_when_action_is_null() + { + // Arrange + // Act + var act = () => EnterCatch.Never(null!); + + // Assert + _ = act.Should().Throw(); + } + + [TestMethod] + public void Never_allows_exception_to_propagate_when_used_in_catch_filter() + { + // Arrange + bool actionExecuted = false; + bool catchBlockEntered = false; + + // Act + var act = () => + { + try + { + throw new InvalidOperationException("Test exception"); + } + catch (InvalidOperationException) when (EnterCatch.Never(() => actionExecuted = true)) + { + catchBlockEntered = true; + } + }; + + // Assert + _ = act.Should().Throw(); + _ = actionExecuted.Should().BeTrue(); + _ = catchBlockEntered.Should().BeFalse(); + } + + [TestMethod] + public void AfterAction_executes_action_and_returns_true() + { + // Arrange + bool actionExecuted = false; + + // Act + bool result = EnterCatch.AfterAction(() => actionExecuted = true); + + // Assert + _ = actionExecuted.Should().BeTrue(); + _ = result.Should().BeTrue(); + } + + [TestMethod] + public void AfterAction_throws_when_action_is_null() + { + // Arrange + // Act + var act = () => EnterCatch.AfterAction(null!); + + // Assert + _ = act.Should().Throw(); + } + + [TestMethod] + public void AfterAction_causes_catch_block_to_execute_when_used_in_catch_filter() + { + // Arrange + bool actionExecuted = false; + bool catchBlockEntered = false; + InvalidOperationException? caughtException = null; + + // Act + try + { + throw new InvalidOperationException("Test exception"); + } + catch (InvalidOperationException ex) when (EnterCatch.AfterAction(() => actionExecuted = true)) + { + catchBlockEntered = true; + caughtException = ex; + } + + // Assert + _ = actionExecuted.Should().BeTrue(); + _ = catchBlockEntered.Should().BeTrue(); + _ = caughtException.Should().NotBeNull(); + _ = caughtException!.Message.Should().Be("Test exception"); + } + + [TestMethod] + public void AfterAction_preserves_exception_context_for_logging() + { + // Arrange + string? loggedMessage = null; + string? loggedStackTrace = null; + + // Act + try + { + throw new InvalidOperationException("Context preserved"); + } + catch (InvalidOperationException ex) when (EnterCatch.AfterAction(() => + { + loggedMessage = ex.Message; + loggedStackTrace = ex.StackTrace; + })) + { + // handle exception + } + + // Assert + _ = loggedMessage.Should().Be("Context preserved"); + _ = loggedStackTrace.Should().NotBeNull(); + } + + [TestMethod] + public void AfterActionIf_executes_action_and_returns_condition_result_when_true() + { + // Arrange + bool actionExecuted = false; + + // Act + bool result = EnterCatch.AfterActionIf( + () => actionExecuted = true, + () => true); + + // Assert + _ = actionExecuted.Should().BeTrue(); + _ = result.Should().BeTrue(); + } + + [TestMethod] + public void AfterActionIf_executes_action_and_returns_condition_result_when_false() + { + // Arrange + bool actionExecuted = false; + + // Act + bool result = EnterCatch.AfterActionIf( + () => actionExecuted = true, + () => false); + + // Assert + _ = actionExecuted.Should().BeTrue(); + _ = result.Should().BeFalse(); + } + + [TestMethod] + public void AfterActionIf_throws_when_action_is_null() + { + // Arrange + // Act + var act = () => EnterCatch.AfterActionIf(null!, () => true); + + // Assert + _ = act.Should().Throw(); + } + + [TestMethod] + public void AfterActionIf_throws_when_condition_is_null() + { + // Arrange + // Act + var act = () => EnterCatch.AfterActionIf(() => { }, null!); + + // Assert + _ = act.Should().Throw(); + } + + [TestMethod] + public void AfterActionIf_enters_catch_block_when_condition_returns_true() + { + // Arrange + bool actionExecuted = false; + bool catchBlockEntered = false; + int retryCount = 0; + int maxRetries = 3; + + // Act + try + { + throw new InvalidOperationException("Test exception"); + } + catch (InvalidOperationException) when (EnterCatch.AfterActionIf( + () => actionExecuted = true, + () => retryCount < maxRetries)) + { + catchBlockEntered = true; + retryCount++; + } + + // Assert + _ = actionExecuted.Should().BeTrue(); + _ = catchBlockEntered.Should().BeTrue(); + _ = retryCount.Should().Be(1); + } + + [TestMethod] + public void AfterActionIf_does_not_enter_catch_block_when_condition_returns_false() + { + // Arrange + bool actionExecuted = false; + bool catchBlockEntered = false; + int retryCount = 5; + int maxRetries = 3; + + // Act + var act = () => + { + try + { + throw new InvalidOperationException("Test exception"); + } + catch (InvalidOperationException) when (EnterCatch.AfterActionIf( + () => actionExecuted = true, + () => retryCount < maxRetries)) + { + catchBlockEntered = true; + } + }; + + // Assert + _ = act.Should().Throw(); + _ = actionExecuted.Should().BeTrue(); + _ = catchBlockEntered.Should().BeFalse(); + } + + [TestMethod] + public void AfterActionIf_executes_action_before_evaluating_condition() + { + // Arrange + int executionOrder = 0; + int actionExecutionOrder = 0; + int conditionExecutionOrder = 0; + + // Act + _ = EnterCatch.AfterActionIf( + () => actionExecutionOrder = ++executionOrder, + () => + { + conditionExecutionOrder = ++executionOrder; + + return true; + }); + + // Assert + _ = actionExecutionOrder.Should().Be(1); + _ = conditionExecutionOrder.Should().Be(2); + } + + [TestMethod] + public void AfterActionIf_allows_condition_to_access_state_modified_by_action() + { + // Arrange + int counter = 0; + + // Act + bool result = EnterCatch.AfterActionIf( + () => counter++, + () => counter > 0); + + // Assert + _ = result.Should().BeTrue(); + _ = counter.Should().Be(1); + } +} From ccd729c9241b5fe2d0f920d53cdedf90d38d1472 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Luis=20Barreda=20G=C3=BCere=C3=B1a?= Date: Sat, 11 Oct 2025 02:39:02 -0700 Subject: [PATCH 4/6] style: fix formatting issue in using directive The `using DevElf.ArgumentValidation;` directive in `EnterCatch.cs` was removed and re-added without any functional changes. This appears to address a formatting or encoding issue, as the directive remains unchanged in functionality. --- src/DevElf/EnterCatch.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DevElf/EnterCatch.cs b/src/DevElf/EnterCatch.cs index 47ba546..88404a5 100644 --- a/src/DevElf/EnterCatch.cs +++ b/src/DevElf/EnterCatch.cs @@ -1,4 +1,4 @@ -using DevElf.ArgumentValidation; +using DevElf.ArgumentValidation; namespace DevElf; From 5decd851f1f94d5d1ddea91a7bd629f0143d364f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Luis=20Barreda=20G=C3=BCere=C3=B1a?= Date: Sat, 18 Oct 2025 01:31:55 -0700 Subject: [PATCH 5/6] feat: add rate limiting, logging, and DI extensions Introduced `NoLimitRateLimiter` and `RateLimiterExtensions` to simplify rate limiting for actions and requests. Added `LoggerExtensions` for fluent logging scope creation and `ServiceCollectionExtensions` for enhanced DI patterns. Comprehensive unit tests were added for all new features, ensuring robust validation of edge cases and concurrency. Updated documentation with examples and details for new classes and methods. Upgraded dependencies, including `System.Threading.RateLimiting`, and updated project files to include new namespaces. --- Directory.Packages.props | 21 +- docs/api/DevElf/DevElf.DependencyInjection.md | 7 + docs/api/DevElf/DevElf.Logging.md | 8 + .../DevElf/DevElf.Threading.RateLimiting.md | 9 + ...s.AddProperty.3HF6MS7LG9TTAZCXIBRQIVMY8.md | 58 + docs/api/DevElf/LoggerExtensions.md | 16 + ...r.AddProperty.ECT6GIFQ7YQ2WQEOEILC883U4.md | 38 + ...gingScopePropertiesBuilder.BeginScope().md | 31 + .../DevElf/LoggingScopePropertiesBuilder.md | 21 + ...uireAsyncCore.9OYNX0BDE4KS06QL3Q6ZAT7E9.md | 30 + ...ptAcquireCore.8MGOY3NOUQFYG8WU0SFKW9RS4.md | 23 + .../NoLimitRateLimiter.GetStatistics().md | 15 + .../DevElf/NoLimitRateLimiter.IdleDuration.md | 14 + .../api/DevElf/NoLimitRateLimiter.Instance.md | 17 + ...imitRateLimiter.NoLimitLease.IsAcquired.md | 14 + ...tRateLimiter.NoLimitLease.LeaseInstance.md | 13 + ...tRateLimiter.NoLimitLease.MetadataNames.md | 14 + ...ryGetMetadata.1WY8B7NIF29S1MB3QC5ZQMBU7.md | 28 + .../DevElf/NoLimitRateLimiter.NoLimitLease.md | 26 + docs/api/DevElf/NoLimitRateLimiter.md | 46 + docs/api/DevElf/README.md | 3 + .../RateLimiterExtensions.ApplyToAsync.md | 204 +++ docs/api/DevElf/RateLimiterExtensions.md | 18 + .../DevElf/ServiceCollectionExtensions.Add.md | 166 +++ ...viceCollectionExtensions.AddFactoryFunc.md | 122 ++ ...CollectionExtensions.AddWithFactoryFunc.md | 176 +++ .../ServiceCollectionExtensions.TryAdd.md | 158 +++ ...eCollectionExtensions.TryAddFactoryFunc.md | 105 ++ ...lectionExtensions.TryAddWithFactoryFunc.md | 161 +++ .../api/DevElf/ServiceCollectionExtensions.md | 32 + .../ServiceCollectionExtensions.cs | 514 ++++++++ src/DevElf/DevElf.csproj | 5 + src/DevElf/Logging/LoggerExtensions.cs | 52 + .../Logging/LoggingScopePropertiesBuilder.cs | 87 ++ .../RateLimiting/NoLimitRateLimiter.cs | 122 ++ .../RateLimiting/RateLimiterExtensions.cs | 221 ++++ .../LoggerExtensionsTests.cs | 146 +++ .../LoggingScopePropertiesBuilderTests.cs | 271 ++++ .../ServiceCollectionExtensionsTests.cs | 1155 +++++++++++++++++ tests/DevElf.Tests/DevElf.Tests.csproj | 1 + .../RateLimiting/NoLimitRateLimiterTests.cs | 339 +++++ .../RateLimiterExtensionsTests.cs | 607 +++++++++ 42 files changed, 5104 insertions(+), 10 deletions(-) create mode 100644 docs/api/DevElf/DevElf.DependencyInjection.md create mode 100644 docs/api/DevElf/DevElf.Logging.md create mode 100644 docs/api/DevElf/DevElf.Threading.RateLimiting.md create mode 100644 docs/api/DevElf/LoggerExtensions.AddProperty.3HF6MS7LG9TTAZCXIBRQIVMY8.md create mode 100644 docs/api/DevElf/LoggerExtensions.md create mode 100644 docs/api/DevElf/LoggingScopePropertiesBuilder.AddProperty.ECT6GIFQ7YQ2WQEOEILC883U4.md create mode 100644 docs/api/DevElf/LoggingScopePropertiesBuilder.BeginScope().md create mode 100644 docs/api/DevElf/LoggingScopePropertiesBuilder.md create mode 100644 docs/api/DevElf/NoLimitRateLimiter.AcquireAsyncCore.9OYNX0BDE4KS06QL3Q6ZAT7E9.md create mode 100644 docs/api/DevElf/NoLimitRateLimiter.AttemptAcquireCore.8MGOY3NOUQFYG8WU0SFKW9RS4.md create mode 100644 docs/api/DevElf/NoLimitRateLimiter.GetStatistics().md create mode 100644 docs/api/DevElf/NoLimitRateLimiter.IdleDuration.md create mode 100644 docs/api/DevElf/NoLimitRateLimiter.Instance.md create mode 100644 docs/api/DevElf/NoLimitRateLimiter.NoLimitLease.IsAcquired.md create mode 100644 docs/api/DevElf/NoLimitRateLimiter.NoLimitLease.LeaseInstance.md create mode 100644 docs/api/DevElf/NoLimitRateLimiter.NoLimitLease.MetadataNames.md create mode 100644 docs/api/DevElf/NoLimitRateLimiter.NoLimitLease.TryGetMetadata.1WY8B7NIF29S1MB3QC5ZQMBU7.md create mode 100644 docs/api/DevElf/NoLimitRateLimiter.NoLimitLease.md create mode 100644 docs/api/DevElf/NoLimitRateLimiter.md create mode 100644 docs/api/DevElf/RateLimiterExtensions.ApplyToAsync.md create mode 100644 docs/api/DevElf/RateLimiterExtensions.md create mode 100644 docs/api/DevElf/ServiceCollectionExtensions.Add.md create mode 100644 docs/api/DevElf/ServiceCollectionExtensions.AddFactoryFunc.md create mode 100644 docs/api/DevElf/ServiceCollectionExtensions.AddWithFactoryFunc.md create mode 100644 docs/api/DevElf/ServiceCollectionExtensions.TryAdd.md create mode 100644 docs/api/DevElf/ServiceCollectionExtensions.TryAddFactoryFunc.md create mode 100644 docs/api/DevElf/ServiceCollectionExtensions.TryAddWithFactoryFunc.md create mode 100644 docs/api/DevElf/ServiceCollectionExtensions.md create mode 100644 src/DevElf/DependencyInjection/ServiceCollectionExtensions.cs create mode 100644 src/DevElf/Logging/LoggerExtensions.cs create mode 100644 src/DevElf/Logging/LoggingScopePropertiesBuilder.cs create mode 100644 src/DevElf/Threading/RateLimiting/NoLimitRateLimiter.cs create mode 100644 src/DevElf/Threading/RateLimiting/RateLimiterExtensions.cs create mode 100644 tests/DevElf.Logging.Tests/LoggerExtensionsTests.cs create mode 100644 tests/DevElf.Logging.Tests/LoggingScopePropertiesBuilderTests.cs create mode 100644 tests/DevElf.Tests/DependencyInjection/ServiceCollectionExtensionsTests.cs create mode 100644 tests/DevElf.Tests/Threading/RateLimiting/NoLimitRateLimiterTests.cs create mode 100644 tests/DevElf.Tests/Threading/RateLimiting/RateLimiterExtensionsTests.cs diff --git a/Directory.Packages.props b/Directory.Packages.props index 28d6857..f144ba3 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -16,7 +16,7 @@ - + @@ -24,21 +24,22 @@ all - - - - - - + + + + + + - - + + runtime; build; native; contentfiles; analyzers; buildtransitive all + @@ -65,4 +66,4 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + \ No newline at end of file diff --git a/docs/api/DevElf/DevElf.DependencyInjection.md b/docs/api/DevElf/DevElf.DependencyInjection.md new file mode 100644 index 0000000..6bbe4d4 --- /dev/null +++ b/docs/api/DevElf/DevElf.DependencyInjection.md @@ -0,0 +1,7 @@ +#### [DevElf](README.md 'README') + +## DevElf\.DependencyInjection Namespace + +| Classes | | +| :--- | :--- | +| [ServiceCollectionExtensions](ServiceCollectionExtensions.md 'DevElf\.DependencyInjection\.ServiceCollectionExtensions') | Extension methods for [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') that simplify service registration and factory function patterns in dependency injection\. | diff --git a/docs/api/DevElf/DevElf.Logging.md b/docs/api/DevElf/DevElf.Logging.md new file mode 100644 index 0000000..e975310 --- /dev/null +++ b/docs/api/DevElf/DevElf.Logging.md @@ -0,0 +1,8 @@ +#### [DevElf](README.md 'README') + +## DevElf\.Logging Namespace + +| Classes | | +| :--- | :--- | +| [LoggerExtensions](LoggerExtensions.md 'DevElf\.Logging\.LoggerExtensions') | Provides extension methods for [Microsoft\.Extensions\.Logging\.ILogger](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.ilogger 'Microsoft\.Extensions\.Logging\.ILogger') to enhance logging capabilities\. | +| [LoggingScopePropertiesBuilder](LoggingScopePropertiesBuilder.md 'DevElf\.Logging\.LoggingScopePropertiesBuilder') | Provides a fluent API for building logging scopes with multiple properties\. | diff --git a/docs/api/DevElf/DevElf.Threading.RateLimiting.md b/docs/api/DevElf/DevElf.Threading.RateLimiting.md new file mode 100644 index 0000000..d9db657 --- /dev/null +++ b/docs/api/DevElf/DevElf.Threading.RateLimiting.md @@ -0,0 +1,9 @@ +#### [DevElf](README.md 'README') + +## DevElf\.Threading\.RateLimiting Namespace + +| Classes | | +| :--- | :--- | +| [NoLimitRateLimiter](NoLimitRateLimiter.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter') | A [System\.Threading\.RateLimiting\.RateLimiter](https://learn.microsoft.com/en-us/dotnet/api/system.threading.ratelimiting.ratelimiter 'System\.Threading\.RateLimiting\.RateLimiter') implementation that imposes no limits on permit acquisition\. All requests for permits are immediately granted without any restrictions\. | +| [NoLimitRateLimiter\.NoLimitLease](NoLimitRateLimiter.NoLimitLease.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter\.NoLimitLease') | Represents a lease from [NoLimitRateLimiter](NoLimitRateLimiter.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter') that is always acquired and contains no metadata\. | +| [RateLimiterExtensions](RateLimiterExtensions.md 'DevElf\.Threading\.RateLimiting\.RateLimiterExtensions') | Provides extension methods for [System\.Threading\.RateLimiting\.RateLimiter](https://learn.microsoft.com/en-us/dotnet/api/system.threading.ratelimiting.ratelimiter 'System\.Threading\.RateLimiting\.RateLimiter') to simplify applying rate limiting to actions and requests\. | diff --git a/docs/api/DevElf/LoggerExtensions.AddProperty.3HF6MS7LG9TTAZCXIBRQIVMY8.md b/docs/api/DevElf/LoggerExtensions.AddProperty.3HF6MS7LG9TTAZCXIBRQIVMY8.md new file mode 100644 index 0000000..a5e0782 --- /dev/null +++ b/docs/api/DevElf/LoggerExtensions.AddProperty.3HF6MS7LG9TTAZCXIBRQIVMY8.md @@ -0,0 +1,58 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Logging](DevElf.Logging.md 'DevElf\.Logging').[LoggerExtensions](LoggerExtensions.md 'DevElf\.Logging\.LoggerExtensions') + +## LoggerExtensions\.AddProperty\(this ILogger, string, object\) Method + +Creates a new logging scope properties builder with the specified property\. + +```csharp +public static DevElf.Logging.LoggingScopePropertiesBuilder AddProperty(this Microsoft.Extensions.Logging.ILogger logger, string name, object? value); +``` +#### Parameters + + + +`logger` [Microsoft\.Extensions\.Logging\.ILogger](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.ilogger 'Microsoft\.Extensions\.Logging\.ILogger') + +The logger instance to create a scope for\. + + + +`name` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the property to add to the logging scope\. + + + +`value` [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') + +The value of the property to add to the logging scope\. + +#### Returns +[LoggingScopePropertiesBuilder](LoggingScopePropertiesBuilder.md 'DevElf\.Logging\.LoggingScopePropertiesBuilder') +A [LoggingScopePropertiesBuilder](LoggingScopePropertiesBuilder.md 'DevElf\.Logging\.LoggingScopePropertiesBuilder') that can be used to add more properties +or begin the logging scope\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +Thrown when [logger](LoggerExtensions.AddProperty.3HF6MS7LG9TTAZCXIBRQIVMY8.md#DevElf.Logging.LoggerExtensions.AddProperty(thisMicrosoft.Extensions.Logging.ILogger,string,object).logger 'DevElf\.Logging\.LoggerExtensions\.AddProperty\(this Microsoft\.Extensions\.Logging\.ILogger, string, object\)\.logger') or [name](LoggerExtensions.AddProperty.3HF6MS7LG9TTAZCXIBRQIVMY8.md#DevElf.Logging.LoggerExtensions.AddProperty(thisMicrosoft.Extensions.Logging.ILogger,string,object).name 'DevElf\.Logging\.LoggerExtensions\.AddProperty\(this Microsoft\.Extensions\.Logging\.ILogger, string, object\)\.name') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + +[System\.ArgumentException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentexception 'System\.ArgumentException') +Thrown when [name](LoggerExtensions.AddProperty.3HF6MS7LG9TTAZCXIBRQIVMY8.md#DevElf.Logging.LoggerExtensions.AddProperty(thisMicrosoft.Extensions.Logging.ILogger,string,object).name 'DevElf\.Logging\.LoggerExtensions\.AddProperty\(this Microsoft\.Extensions\.Logging\.ILogger, string, object\)\.name') is empty or contains only whitespace\. + +### Example + +```csharp +using (logger.AddProperty("UserId", userId) + .AddProperty("RequestId", requestId) + .BeginScope()) +{ + logger.LogInformation("Processing request"); +} +``` + +### Remarks +This method provides a fluent API for building logging scopes with multiple properties\. +Use the returned builder to add additional properties via [AddProperty\(string, object\)](LoggingScopePropertiesBuilder.AddProperty.ECT6GIFQ7YQ2WQEOEILC883U4.md 'DevElf\.Logging\.LoggingScopePropertiesBuilder\.AddProperty\(string, object\)') +and then call [BeginScope\(\)](LoggingScopePropertiesBuilder.BeginScope().md 'DevElf\.Logging\.LoggingScopePropertiesBuilder\.BeginScope\(\)') to create the scope\. \ No newline at end of file diff --git a/docs/api/DevElf/LoggerExtensions.md b/docs/api/DevElf/LoggerExtensions.md new file mode 100644 index 0000000..54cbe4b --- /dev/null +++ b/docs/api/DevElf/LoggerExtensions.md @@ -0,0 +1,16 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Logging](DevElf.Logging.md 'DevElf\.Logging') + +## LoggerExtensions Class + +Provides extension methods for [Microsoft\.Extensions\.Logging\.ILogger](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.ilogger 'Microsoft\.Extensions\.Logging\.ILogger') to enhance logging capabilities\. + +```csharp +public static class LoggerExtensions +``` + +Inheritance [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') 🡒 LoggerExtensions + +| Methods | | +| :--- | :--- | +| [AddProperty\(this ILogger, string, object\)](LoggerExtensions.AddProperty.3HF6MS7LG9TTAZCXIBRQIVMY8.md 'DevElf\.Logging\.LoggerExtensions\.AddProperty\(this Microsoft\.Extensions\.Logging\.ILogger, string, object\)') | Creates a new logging scope properties builder with the specified property\. | diff --git a/docs/api/DevElf/LoggingScopePropertiesBuilder.AddProperty.ECT6GIFQ7YQ2WQEOEILC883U4.md b/docs/api/DevElf/LoggingScopePropertiesBuilder.AddProperty.ECT6GIFQ7YQ2WQEOEILC883U4.md new file mode 100644 index 0000000..0f3857b --- /dev/null +++ b/docs/api/DevElf/LoggingScopePropertiesBuilder.AddProperty.ECT6GIFQ7YQ2WQEOEILC883U4.md @@ -0,0 +1,38 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Logging](DevElf.Logging.md 'DevElf\.Logging').[LoggingScopePropertiesBuilder](LoggingScopePropertiesBuilder.md 'DevElf\.Logging\.LoggingScopePropertiesBuilder') + +## LoggingScopePropertiesBuilder\.AddProperty\(string, object\) Method + +Adds or updates a property in the logging scope\. + +```csharp +public DevElf.Logging.LoggingScopePropertiesBuilder AddProperty(string name, object? value); +``` +#### Parameters + + + +`name` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the property to add or update\. + + + +`value` [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') + +The value of the property\. + +#### Returns +[LoggingScopePropertiesBuilder](LoggingScopePropertiesBuilder.md 'DevElf\.Logging\.LoggingScopePropertiesBuilder') +The current [LoggingScopePropertiesBuilder](LoggingScopePropertiesBuilder.md 'DevElf\.Logging\.LoggingScopePropertiesBuilder') instance for method chaining\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +Thrown when [name](LoggingScopePropertiesBuilder.AddProperty.ECT6GIFQ7YQ2WQEOEILC883U4.md#DevElf.Logging.LoggingScopePropertiesBuilder.AddProperty(string,object).name 'DevElf\.Logging\.LoggingScopePropertiesBuilder\.AddProperty\(string, object\)\.name') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + +[System\.ArgumentException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentexception 'System\.ArgumentException') +Thrown when [name](LoggingScopePropertiesBuilder.AddProperty.ECT6GIFQ7YQ2WQEOEILC883U4.md#DevElf.Logging.LoggingScopePropertiesBuilder.AddProperty(string,object).name 'DevElf\.Logging\.LoggingScopePropertiesBuilder\.AddProperty\(string, object\)\.name') is empty or contains only whitespace\. + +### Remarks +If a property with the same name already exists, its value will be replaced with the new value\. \ No newline at end of file diff --git a/docs/api/DevElf/LoggingScopePropertiesBuilder.BeginScope().md b/docs/api/DevElf/LoggingScopePropertiesBuilder.BeginScope().md new file mode 100644 index 0000000..a74514e --- /dev/null +++ b/docs/api/DevElf/LoggingScopePropertiesBuilder.BeginScope().md @@ -0,0 +1,31 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Logging](DevElf.Logging.md 'DevElf\.Logging').[LoggingScopePropertiesBuilder](LoggingScopePropertiesBuilder.md 'DevElf\.Logging\.LoggingScopePropertiesBuilder') + +## LoggingScopePropertiesBuilder\.BeginScope\(\) Method + +Begins a new logging scope with all the properties that have been added\. + +```csharp +public System.IDisposable? BeginScope(); +``` + +#### Returns +[System\.IDisposable](https://learn.microsoft.com/en-us/dotnet/api/system.idisposable 'System\.IDisposable') +An [System\.IDisposable](https://learn.microsoft.com/en-us/dotnet/api/system.idisposable 'System\.IDisposable') that ends the scope when disposed, or [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null') +if the logger does not support scopes\. + +### Example + +```csharp +using (logger.AddProperty("UserId", userId) + .AddProperty("OperationId", operationId) + .BeginScope()) +{ + logger.LogInformation("Operation started"); + // All logs within this scope will include UserId and OperationId +} +``` + +### Remarks +The returned [System\.IDisposable](https://learn.microsoft.com/en-us/dotnet/api/system.idisposable 'System\.IDisposable') should be disposed to properly end the logging scope\. +It's recommended to use this within a [using](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/using') statement to ensure proper cleanup\. \ No newline at end of file diff --git a/docs/api/DevElf/LoggingScopePropertiesBuilder.md b/docs/api/DevElf/LoggingScopePropertiesBuilder.md new file mode 100644 index 0000000..d00688e --- /dev/null +++ b/docs/api/DevElf/LoggingScopePropertiesBuilder.md @@ -0,0 +1,21 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Logging](DevElf.Logging.md 'DevElf\.Logging') + +## LoggingScopePropertiesBuilder Class + +Provides a fluent API for building logging scopes with multiple properties\. + +```csharp +public sealed class LoggingScopePropertiesBuilder +``` + +Inheritance [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') 🡒 LoggingScopePropertiesBuilder + +### Remarks +This class is typically created using the [AddProperty\(this ILogger, string, object\)](LoggerExtensions.AddProperty.3HF6MS7LG9TTAZCXIBRQIVMY8.md 'DevElf\.Logging\.LoggerExtensions\.AddProperty\(this Microsoft\.Extensions\.Logging\.ILogger, string, object\)') extension method +and allows chaining multiple property additions before beginning the scope\. + +| Methods | | +| :--- | :--- | +| [AddProperty\(string, object\)](LoggingScopePropertiesBuilder.AddProperty.ECT6GIFQ7YQ2WQEOEILC883U4.md 'DevElf\.Logging\.LoggingScopePropertiesBuilder\.AddProperty\(string, object\)') | Adds or updates a property in the logging scope\. | +| [BeginScope\(\)](LoggingScopePropertiesBuilder.BeginScope().md 'DevElf\.Logging\.LoggingScopePropertiesBuilder\.BeginScope\(\)') | Begins a new logging scope with all the properties that have been added\. | diff --git a/docs/api/DevElf/NoLimitRateLimiter.AcquireAsyncCore.9OYNX0BDE4KS06QL3Q6ZAT7E9.md b/docs/api/DevElf/NoLimitRateLimiter.AcquireAsyncCore.9OYNX0BDE4KS06QL3Q6ZAT7E9.md new file mode 100644 index 0000000..eb8d537 --- /dev/null +++ b/docs/api/DevElf/NoLimitRateLimiter.AcquireAsyncCore.9OYNX0BDE4KS06QL3Q6ZAT7E9.md @@ -0,0 +1,30 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Threading\.RateLimiting](DevElf.Threading.RateLimiting.md 'DevElf\.Threading\.RateLimiting').[NoLimitRateLimiter](NoLimitRateLimiter.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter') + +## NoLimitRateLimiter\.AcquireAsyncCore\(int, CancellationToken\) Method + +Asynchronously acquires permits\. Always succeeds immediately regardless of +the permit count\. + +```csharp +protected override System.Threading.Tasks.ValueTask AcquireAsyncCore(int permitCount, System.Threading.CancellationToken cancellationToken); +``` +#### Parameters + + + +`permitCount` [System\.Int32](https://learn.microsoft.com/en-us/dotnet/api/system.int32 'System\.Int32') + +The number of permits to acquire\. This parameter is ignored since all +acquisitions succeed\. + + + +`cancellationToken` [System\.Threading\.CancellationToken](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken 'System\.Threading\.CancellationToken') + +A token to monitor for cancellation requests\. This parameter is ignored since +the operation completes synchronously\. + +#### Returns +[System\.Threading\.Tasks\.ValueTask<](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.valuetask-1 'System\.Threading\.Tasks\.ValueTask\`1')[System\.Threading\.RateLimiting\.RateLimitLease](https://learn.microsoft.com/en-us/dotnet/api/system.threading.ratelimiting.ratelimitlease 'System\.Threading\.RateLimiting\.RateLimitLease')[>](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.valuetask-1 'System\.Threading\.Tasks\.ValueTask\`1') +A [System\.Threading\.Tasks\.ValueTask<>](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.valuetask-1 'System\.Threading\.Tasks\.ValueTask\`1') that completes immediately with an acquired lease\. \ No newline at end of file diff --git a/docs/api/DevElf/NoLimitRateLimiter.AttemptAcquireCore.8MGOY3NOUQFYG8WU0SFKW9RS4.md b/docs/api/DevElf/NoLimitRateLimiter.AttemptAcquireCore.8MGOY3NOUQFYG8WU0SFKW9RS4.md new file mode 100644 index 0000000..9333e67 --- /dev/null +++ b/docs/api/DevElf/NoLimitRateLimiter.AttemptAcquireCore.8MGOY3NOUQFYG8WU0SFKW9RS4.md @@ -0,0 +1,23 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Threading\.RateLimiting](DevElf.Threading.RateLimiting.md 'DevElf\.Threading\.RateLimiting').[NoLimitRateLimiter](NoLimitRateLimiter.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter') + +## NoLimitRateLimiter\.AttemptAcquireCore\(int\) Method + +Attempts to acquire permits synchronously\. Always succeeds immediately +regardless of the permit count\. + +```csharp +protected override System.Threading.RateLimiting.RateLimitLease AttemptAcquireCore(int permitCount); +``` +#### Parameters + + + +`permitCount` [System\.Int32](https://learn.microsoft.com/en-us/dotnet/api/system.int32 'System\.Int32') + +The number of permits to acquire\. This parameter is ignored since all +acquisitions succeed\. + +#### Returns +[System\.Threading\.RateLimiting\.RateLimitLease](https://learn.microsoft.com/en-us/dotnet/api/system.threading.ratelimiting.ratelimitlease 'System\.Threading\.RateLimiting\.RateLimitLease') +An acquired [System\.Threading\.RateLimiting\.RateLimitLease](https://learn.microsoft.com/en-us/dotnet/api/system.threading.ratelimiting.ratelimitlease 'System\.Threading\.RateLimiting\.RateLimitLease')\. \ No newline at end of file diff --git a/docs/api/DevElf/NoLimitRateLimiter.GetStatistics().md b/docs/api/DevElf/NoLimitRateLimiter.GetStatistics().md new file mode 100644 index 0000000..7b0d422 --- /dev/null +++ b/docs/api/DevElf/NoLimitRateLimiter.GetStatistics().md @@ -0,0 +1,15 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Threading\.RateLimiting](DevElf.Threading.RateLimiting.md 'DevElf\.Threading\.RateLimiting').[NoLimitRateLimiter](NoLimitRateLimiter.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter') + +## NoLimitRateLimiter\.GetStatistics\(\) Method + +Gets the rate limiter statistics\. Always returns [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null') since +this limiter does not track any statistics\. + +```csharp +public override System.Threading.RateLimiting.RateLimiterStatistics? GetStatistics(); +``` + +#### Returns +[System\.Threading\.RateLimiting\.RateLimiterStatistics](https://learn.microsoft.com/en-us/dotnet/api/system.threading.ratelimiting.ratelimiterstatistics 'System\.Threading\.RateLimiting\.RateLimiterStatistics') +Always [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. \ No newline at end of file diff --git a/docs/api/DevElf/NoLimitRateLimiter.IdleDuration.md b/docs/api/DevElf/NoLimitRateLimiter.IdleDuration.md new file mode 100644 index 0000000..4686dbb --- /dev/null +++ b/docs/api/DevElf/NoLimitRateLimiter.IdleDuration.md @@ -0,0 +1,14 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Threading\.RateLimiting](DevElf.Threading.RateLimiting.md 'DevElf\.Threading\.RateLimiting').[NoLimitRateLimiter](NoLimitRateLimiter.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter') + +## NoLimitRateLimiter\.IdleDuration Property + +Gets the idle duration, which is always [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null') for this limiter +since there is never any waiting required\. + +```csharp +public override System.Nullable IdleDuration { get; } +``` + +#### Property Value +[System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[System\.TimeSpan](https://learn.microsoft.com/en-us/dotnet/api/system.timespan 'System\.TimeSpan')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') \ No newline at end of file diff --git a/docs/api/DevElf/NoLimitRateLimiter.Instance.md b/docs/api/DevElf/NoLimitRateLimiter.Instance.md new file mode 100644 index 0000000..63fe3bd --- /dev/null +++ b/docs/api/DevElf/NoLimitRateLimiter.Instance.md @@ -0,0 +1,17 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Threading\.RateLimiting](DevElf.Threading.RateLimiting.md 'DevElf\.Threading\.RateLimiting').[NoLimitRateLimiter](NoLimitRateLimiter.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter') + +## NoLimitRateLimiter\.Instance Field + +Gets the singleton instance of [NoLimitRateLimiter](NoLimitRateLimiter.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter')\. + +```csharp +public static readonly NoLimitRateLimiter Instance; +``` + +#### Field Value +[NoLimitRateLimiter](NoLimitRateLimiter.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter') + +### Remarks +Using this instance avoids creating multiple instances of the same +no\-op rate limiter\. \ No newline at end of file diff --git a/docs/api/DevElf/NoLimitRateLimiter.NoLimitLease.IsAcquired.md b/docs/api/DevElf/NoLimitRateLimiter.NoLimitLease.IsAcquired.md new file mode 100644 index 0000000..3d0cc7e --- /dev/null +++ b/docs/api/DevElf/NoLimitRateLimiter.NoLimitLease.IsAcquired.md @@ -0,0 +1,14 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Threading\.RateLimiting](DevElf.Threading.RateLimiting.md 'DevElf\.Threading\.RateLimiting').[NoLimitRateLimiter](NoLimitRateLimiter.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter').[NoLimitLease](NoLimitRateLimiter.NoLimitLease.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter\.NoLimitLease') + +## NoLimitRateLimiter\.NoLimitLease\.IsAcquired Property + +Gets a value indicating whether the lease was acquired\. Always returns +[true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool')\. + +```csharp +public override bool IsAcquired { get; } +``` + +#### Property Value +[System\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean') \ No newline at end of file diff --git a/docs/api/DevElf/NoLimitRateLimiter.NoLimitLease.LeaseInstance.md b/docs/api/DevElf/NoLimitRateLimiter.NoLimitLease.LeaseInstance.md new file mode 100644 index 0000000..f6dcfa8 --- /dev/null +++ b/docs/api/DevElf/NoLimitRateLimiter.NoLimitLease.LeaseInstance.md @@ -0,0 +1,13 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Threading\.RateLimiting](DevElf.Threading.RateLimiting.md 'DevElf\.Threading\.RateLimiting').[NoLimitRateLimiter](NoLimitRateLimiter.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter').[NoLimitLease](NoLimitRateLimiter.NoLimitLease.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter\.NoLimitLease') + +## NoLimitRateLimiter\.NoLimitLease\.LeaseInstance Field + +Gets the singleton instance of [NoLimitLease](NoLimitRateLimiter.NoLimitLease.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter\.NoLimitLease')\. + +```csharp +public static readonly RateLimitLease LeaseInstance; +``` + +#### Field Value +[System\.Threading\.RateLimiting\.RateLimitLease](https://learn.microsoft.com/en-us/dotnet/api/system.threading.ratelimiting.ratelimitlease 'System\.Threading\.RateLimiting\.RateLimitLease') \ No newline at end of file diff --git a/docs/api/DevElf/NoLimitRateLimiter.NoLimitLease.MetadataNames.md b/docs/api/DevElf/NoLimitRateLimiter.NoLimitLease.MetadataNames.md new file mode 100644 index 0000000..28dfc41 --- /dev/null +++ b/docs/api/DevElf/NoLimitRateLimiter.NoLimitLease.MetadataNames.md @@ -0,0 +1,14 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Threading\.RateLimiting](DevElf.Threading.RateLimiting.md 'DevElf\.Threading\.RateLimiting').[NoLimitRateLimiter](NoLimitRateLimiter.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter').[NoLimitLease](NoLimitRateLimiter.NoLimitLease.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter\.NoLimitLease') + +## NoLimitRateLimiter\.NoLimitLease\.MetadataNames Property + +Gets the metadata names associated with this lease\. Always returns an +empty collection since this lease contains no metadata\. + +```csharp +public override System.Collections.Generic.IEnumerable MetadataNames { get; } +``` + +#### Property Value +[System\.Collections\.Generic\.IEnumerable<](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 'System\.Collections\.Generic\.IEnumerable\`1')[System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String')[>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 'System\.Collections\.Generic\.IEnumerable\`1') \ No newline at end of file diff --git a/docs/api/DevElf/NoLimitRateLimiter.NoLimitLease.TryGetMetadata.1WY8B7NIF29S1MB3QC5ZQMBU7.md b/docs/api/DevElf/NoLimitRateLimiter.NoLimitLease.TryGetMetadata.1WY8B7NIF29S1MB3QC5ZQMBU7.md new file mode 100644 index 0000000..211c112 --- /dev/null +++ b/docs/api/DevElf/NoLimitRateLimiter.NoLimitLease.TryGetMetadata.1WY8B7NIF29S1MB3QC5ZQMBU7.md @@ -0,0 +1,28 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Threading\.RateLimiting](DevElf.Threading.RateLimiting.md 'DevElf\.Threading\.RateLimiting').[NoLimitRateLimiter](NoLimitRateLimiter.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter').[NoLimitLease](NoLimitRateLimiter.NoLimitLease.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter\.NoLimitLease') + +## NoLimitRateLimiter\.NoLimitLease\.TryGetMetadata\(string, object\) Method + +Attempts to retrieve metadata by name\. Always returns [false](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool') +since this lease contains no metadata\. + +```csharp +public override bool TryGetMetadata(string metadataName, out object? metadata); +``` +#### Parameters + + + +`metadataName` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') + +The name of the metadata to retrieve\. + + + +`metadata` [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') + +When this method returns, contains [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + +#### Returns +[System\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean') +Always [false](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool')\. \ No newline at end of file diff --git a/docs/api/DevElf/NoLimitRateLimiter.NoLimitLease.md b/docs/api/DevElf/NoLimitRateLimiter.NoLimitLease.md new file mode 100644 index 0000000..11ae5ed --- /dev/null +++ b/docs/api/DevElf/NoLimitRateLimiter.NoLimitLease.md @@ -0,0 +1,26 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Threading\.RateLimiting](DevElf.Threading.RateLimiting.md 'DevElf\.Threading\.RateLimiting').[NoLimitRateLimiter](NoLimitRateLimiter.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter') + +## NoLimitRateLimiter\.NoLimitLease Class + +Represents a lease from [NoLimitRateLimiter](NoLimitRateLimiter.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter') that is always acquired +and contains no metadata\. + +```csharp +protected sealed class NoLimitRateLimiter.NoLimitLease : System.Threading.RateLimiting.RateLimitLease +``` + +Inheritance [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') 🡒 [System\.Threading\.RateLimiting\.RateLimitLease](https://learn.microsoft.com/en-us/dotnet/api/system.threading.ratelimiting.ratelimitlease 'System\.Threading\.RateLimiting\.RateLimitLease') 🡒 NoLimitLease + +| Fields | | +| :--- | :--- | +| [LeaseInstance](NoLimitRateLimiter.NoLimitLease.LeaseInstance.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter\.NoLimitLease\.LeaseInstance') | Gets the singleton instance of [NoLimitLease](NoLimitRateLimiter.NoLimitLease.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter\.NoLimitLease')\. | + +| Properties | | +| :--- | :--- | +| [IsAcquired](NoLimitRateLimiter.NoLimitLease.IsAcquired.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter\.NoLimitLease\.IsAcquired') | Gets a value indicating whether the lease was acquired\. Always returns [true](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool')\. | +| [MetadataNames](NoLimitRateLimiter.NoLimitLease.MetadataNames.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter\.NoLimitLease\.MetadataNames') | Gets the metadata names associated with this lease\. Always returns an empty collection since this lease contains no metadata\. | + +| Methods | | +| :--- | :--- | +| [TryGetMetadata\(string, object\)](NoLimitRateLimiter.NoLimitLease.TryGetMetadata.1WY8B7NIF29S1MB3QC5ZQMBU7.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter\.NoLimitLease\.TryGetMetadata\(string, object\)') | Attempts to retrieve metadata by name\. Always returns [false](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/builtin\-types/bool') since this lease contains no metadata\. | diff --git a/docs/api/DevElf/NoLimitRateLimiter.md b/docs/api/DevElf/NoLimitRateLimiter.md new file mode 100644 index 0000000..34aac28 --- /dev/null +++ b/docs/api/DevElf/NoLimitRateLimiter.md @@ -0,0 +1,46 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Threading\.RateLimiting](DevElf.Threading.RateLimiting.md 'DevElf\.Threading\.RateLimiting') + +## NoLimitRateLimiter Class + +A [System\.Threading\.RateLimiting\.RateLimiter](https://learn.microsoft.com/en-us/dotnet/api/system.threading.ratelimiting.ratelimiter 'System\.Threading\.RateLimiting\.RateLimiter') implementation that imposes no limits on permit acquisition\. +All requests for permits are immediately granted without any restrictions\. + +```csharp +public class NoLimitRateLimiter : System.Threading.RateLimiting.RateLimiter +``` + +Inheritance [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') 🡒 [System\.Threading\.RateLimiting\.RateLimiter](https://learn.microsoft.com/en-us/dotnet/api/system.threading.ratelimiting.ratelimiter 'System\.Threading\.RateLimiting\.RateLimiter') 🡒 NoLimitRateLimiter + +### Example + +```csharp +// Use the singleton instance +RateLimiter limiter = NoLimitRateLimiter.Instance; + +// All acquisitions succeed immediately +using var lease = await limiter.AcquireAsync(permitCount: 100); +// lease.IsAcquired will always be true +``` + +### Remarks + +This rate limiter is useful in scenarios where rate limiting needs to be conditionally +disabled or for testing purposes. It always returns acquired leases immediately, +regardless of the number of permits requested. + +Use the singleton [Instance](NoLimitRateLimiter.Instance.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter\.Instance') to avoid unnecessary allocations. + +| Fields | | +| :--- | :--- | +| [Instance](NoLimitRateLimiter.Instance.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter\.Instance') | Gets the singleton instance of [NoLimitRateLimiter](NoLimitRateLimiter.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter')\. | + +| Properties | | +| :--- | :--- | +| [IdleDuration](NoLimitRateLimiter.IdleDuration.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter\.IdleDuration') | Gets the idle duration, which is always [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null') for this limiter since there is never any waiting required\. | + +| Methods | | +| :--- | :--- | +| [AcquireAsyncCore\(int, CancellationToken\)](NoLimitRateLimiter.AcquireAsyncCore.9OYNX0BDE4KS06QL3Q6ZAT7E9.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter\.AcquireAsyncCore\(int, System\.Threading\.CancellationToken\)') | Asynchronously acquires permits\. Always succeeds immediately regardless of the permit count\. | +| [AttemptAcquireCore\(int\)](NoLimitRateLimiter.AttemptAcquireCore.8MGOY3NOUQFYG8WU0SFKW9RS4.md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter\.AttemptAcquireCore\(int\)') | Attempts to acquire permits synchronously\. Always succeeds immediately regardless of the permit count\. | +| [GetStatistics\(\)](NoLimitRateLimiter.GetStatistics().md 'DevElf\.Threading\.RateLimiting\.NoLimitRateLimiter\.GetStatistics\(\)') | Gets the rate limiter statistics\. Always returns [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null') since this limiter does not track any statistics\. | diff --git a/docs/api/DevElf/README.md b/docs/api/DevElf/README.md index c838230..42e19f3 100644 --- a/docs/api/DevElf/README.md +++ b/docs/api/DevElf/README.md @@ -6,4 +6,7 @@ | :--- | :--- | | [DevElf](DevElf.md 'DevElf') | | | [DevElf\.ArgumentValidation](DevElf.ArgumentValidation.md 'DevElf\.ArgumentValidation') | | +| [DevElf\.DependencyInjection](DevElf.DependencyInjection.md 'DevElf\.DependencyInjection') | | | [DevElf\.Extensions](DevElf.Extensions.md 'DevElf\.Extensions') | | +| [DevElf\.Logging](DevElf.Logging.md 'DevElf\.Logging') | | +| [DevElf\.Threading\.RateLimiting](DevElf.Threading.RateLimiting.md 'DevElf\.Threading\.RateLimiting') | | diff --git a/docs/api/DevElf/RateLimiterExtensions.ApplyToAsync.md b/docs/api/DevElf/RateLimiterExtensions.ApplyToAsync.md new file mode 100644 index 0000000..5288621 --- /dev/null +++ b/docs/api/DevElf/RateLimiterExtensions.ApplyToAsync.md @@ -0,0 +1,204 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Threading\.RateLimiting](DevElf.Threading.RateLimiting.md 'DevElf\.Threading\.RateLimiting').[RateLimiterExtensions](RateLimiterExtensions.md 'DevElf\.Threading\.RateLimiting\.RateLimiterExtensions') + +## RateLimiterExtensions\.ApplyToAsync Method + +| Overloads | | +| :--- | :--- | +| [ApplyToAsync\(this RateLimiter, Func<CancellationToken,Task>, int, Nullable<TimeSpan>, TimeProvider, CancellationToken\)](RateLimiterExtensions.ApplyToAsync.md#DevElf.Threading.RateLimiting.RateLimiterExtensions.ApplyToAsync(thisSystem.Threading.RateLimiting.RateLimiter,System.Func_System.Threading.CancellationToken,System.Threading.Tasks.Task_,int,System.Nullable_System.TimeSpan_,System.TimeProvider,System.Threading.CancellationToken) 'DevElf\.Threading\.RateLimiting\.RateLimiterExtensions\.ApplyToAsync\(this System\.Threading\.RateLimiting\.RateLimiter, System\.Func\, int, System\.Nullable\, System\.TimeProvider, System\.Threading\.CancellationToken\)') | Applies rate limiting to an asynchronous action, automatically acquiring and releasing permits\. | +| [ApplyToAsync<T>\(this RateLimiter, Func<CancellationToken,Task<T>>, int, Nullable<TimeSpan>, TimeProvider, CancellationToken\)](RateLimiterExtensions.ApplyToAsync.md#DevElf.Threading.RateLimiting.RateLimiterExtensions.ApplyToAsync_T_(thisSystem.Threading.RateLimiting.RateLimiter,System.Func_System.Threading.CancellationToken,System.Threading.Tasks.Task_T__,int,System.Nullable_System.TimeSpan_,System.TimeProvider,System.Threading.CancellationToken) 'DevElf\.Threading\.RateLimiting\.RateLimiterExtensions\.ApplyToAsync\\(this System\.Threading\.RateLimiting\.RateLimiter, System\.Func\\>, int, System\.Nullable\, System\.TimeProvider, System\.Threading\.CancellationToken\)') | Applies rate limiting to an asynchronous request, automatically acquiring and releasing permits, and returns the result\. | + + + +## RateLimiterExtensions\.ApplyToAsync\(this RateLimiter, Func\, int, Nullable\, TimeProvider, CancellationToken\) Method + +Applies rate limiting to an asynchronous action, automatically acquiring and +releasing permits\. + +```csharp +public static System.Threading.Tasks.Task ApplyToAsync(this System.Threading.RateLimiting.RateLimiter limiter, System.Func action, int permitCount=1, System.Nullable idleTime=null, System.TimeProvider? timeProvider=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken)); +``` +#### Parameters + + + +`limiter` [System\.Threading\.RateLimiting\.RateLimiter](https://learn.microsoft.com/en-us/dotnet/api/system.threading.ratelimiting.ratelimiter 'System\.Threading\.RateLimiting\.RateLimiter') + +The rate limiter to be used\. + + + +`action` [System\.Func<](https://learn.microsoft.com/en-us/dotnet/api/system.func-2 'System\.Func\`2')[System\.Threading\.CancellationToken](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken 'System\.Threading\.CancellationToken')[,](https://learn.microsoft.com/en-us/dotnet/api/system.func-2 'System\.Func\`2')[System\.Threading\.Tasks\.Task](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task 'System\.Threading\.Tasks\.Task')[>](https://learn.microsoft.com/en-us/dotnet/api/system.func-2 'System\.Func\`2') + +The action to execute once permits are acquired\. + + + +`permitCount` [System\.Int32](https://learn.microsoft.com/en-us/dotnet/api/system.int32 'System\.Int32') + +The number of permits needed to execute the action\. Must be positive\. +Defaults to 1\. + + + +`idleTime` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[System\.TimeSpan](https://learn.microsoft.com/en-us/dotnet/api/system.timespan 'System\.TimeSpan')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The time to wait between permit acquisition attempts when permits are not +immediately available\. When [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null'), defaults to 100 +microseconds\. This prevents busy\-waiting while allowing responsive permit +acquisition\. + + + +`timeProvider` [System\.TimeProvider](https://learn.microsoft.com/en-us/dotnet/api/system.timeprovider 'System\.TimeProvider') + +The [System\.TimeProvider](https://learn.microsoft.com/en-us/dotnet/api/system.timeprovider 'System\.TimeProvider') to use for time\-based operations during idle +waits\. When [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null'), defaults to [System\.TimeProvider\.System](https://learn.microsoft.com/en-us/dotnet/api/system.timeprovider.system 'System\.TimeProvider\.System')\. + + + +`cancellationToken` [System\.Threading\.CancellationToken](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken 'System\.Threading\.CancellationToken') + +A token to monitor for cancellation requests during permit acquisition and +action execution\. + +#### Returns +[System\.Threading\.Tasks\.Task](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task 'System\.Threading\.Tasks\.Task') +A task that completes when the action has been executed\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +If [limiter](RateLimiterExtensions.md#DevElf.Threading.RateLimiting.RateLimiterExtensions.ApplyToAsync(thisSystem.Threading.RateLimiting.RateLimiter,System.Func_System.Threading.CancellationToken,System.Threading.Tasks.Task_,int,System.Nullable_System.TimeSpan_,System.TimeProvider,System.Threading.CancellationToken).limiter 'DevElf\.Threading\.RateLimiting\.RateLimiterExtensions\.ApplyToAsync\(this System\.Threading\.RateLimiting\.RateLimiter, System\.Func\, int, System\.Nullable\, System\.TimeProvider, System\.Threading\.CancellationToken\)\.limiter') or [action](RateLimiterExtensions.md#DevElf.Threading.RateLimiting.RateLimiterExtensions.ApplyToAsync(thisSystem.Threading.RateLimiting.RateLimiter,System.Func_System.Threading.CancellationToken,System.Threading.Tasks.Task_,int,System.Nullable_System.TimeSpan_,System.TimeProvider,System.Threading.CancellationToken).action 'DevElf\.Threading\.RateLimiting\.RateLimiterExtensions\.ApplyToAsync\(this System\.Threading\.RateLimiting\.RateLimiter, System\.Func\, int, System\.Nullable\, System\.TimeProvider, System\.Threading\.CancellationToken\)\.action') is +[null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + +[System\.OperationCanceledException](https://learn.microsoft.com/en-us/dotnet/api/system.operationcanceledexception 'System\.OperationCanceledException') +If the [cancellationToken](RateLimiterExtensions.md#DevElf.Threading.RateLimiting.RateLimiterExtensions.ApplyToAsync(thisSystem.Threading.RateLimiting.RateLimiter,System.Func_System.Threading.CancellationToken,System.Threading.Tasks.Task_,int,System.Nullable_System.TimeSpan_,System.TimeProvider,System.Threading.CancellationToken).cancellationToken 'DevElf\.Threading\.RateLimiting\.RateLimiterExtensions\.ApplyToAsync\(this System\.Threading\.RateLimiting\.RateLimiter, System\.Func\, int, System\.Nullable\, System\.TimeProvider, System\.Threading\.CancellationToken\)\.cancellationToken') is canceled before or during +execution\. + +### Example + +```csharp +var limiter = new TokenBucketRateLimiter(new TokenBucketRateLimiterOptions +{ + TokenLimit = 10, + ReplenishmentPeriod = TimeSpan.FromSeconds(1), + TokensPerPeriod = 10 +}); + +await limiter.ApplyToAsync( + async ct => await SendEmailAsync(ct), + permitCount: 1, + cancellationToken: cancellationToken); +``` + +### Remarks + +This method repeatedly attempts to acquire the specified number of permits. +If permits are not immediately available, it waits for the specified +[idleTime](RateLimiterExtensions.md#DevElf.Threading.RateLimiting.RateLimiterExtensions.ApplyToAsync(thisSystem.Threading.RateLimiting.RateLimiter,System.Func_System.Threading.CancellationToken,System.Threading.Tasks.Task_,int,System.Nullable_System.TimeSpan_,System.TimeProvider,System.Threading.CancellationToken).idleTime 'DevElf\.Threading\.RateLimiting\.RateLimiterExtensions\.ApplyToAsync\(this System\.Threading\.RateLimiting\.RateLimiter, System\.Func\, int, System\.Nullable\, System\.TimeProvider, System\.Threading\.CancellationToken\)\.idleTime') before trying again. Once permits are acquired, +the action is executed and the permits are automatically released. + +The lease is properly disposed even if the action throws an exception, +ensuring permits are returned to the limiter. + + + +## RateLimiterExtensions\.ApplyToAsync\\(this RateLimiter, Func\\>, int, Nullable\, TimeProvider, CancellationToken\) Method + +Applies rate limiting to an asynchronous request, automatically acquiring and +releasing permits, and returns the result\. + +```csharp +public static System.Threading.Tasks.Task ApplyToAsync(this System.Threading.RateLimiting.RateLimiter limiter, System.Func> request, int permitCount=1, System.Nullable idleTime=null, System.TimeProvider? timeProvider=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken)); +``` +#### Type parameters + + + +`T` + +The type of the result returned by the request\. +#### Parameters + + + +`limiter` [System\.Threading\.RateLimiting\.RateLimiter](https://learn.microsoft.com/en-us/dotnet/api/system.threading.ratelimiting.ratelimiter 'System\.Threading\.RateLimiting\.RateLimiter') + +The rate limiter to be used\. + + + +`request` [System\.Func<](https://learn.microsoft.com/en-us/dotnet/api/system.func-2 'System\.Func\`2')[System\.Threading\.CancellationToken](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken 'System\.Threading\.CancellationToken')[,](https://learn.microsoft.com/en-us/dotnet/api/system.func-2 'System\.Func\`2')[System\.Threading\.Tasks\.Task<](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1 'System\.Threading\.Tasks\.Task\`1')[T](RateLimiterExtensions.md#DevElf.Threading.RateLimiting.RateLimiterExtensions.ApplyToAsync_T_(thisSystem.Threading.RateLimiting.RateLimiter,System.Func_System.Threading.CancellationToken,System.Threading.Tasks.Task_T__,int,System.Nullable_System.TimeSpan_,System.TimeProvider,System.Threading.CancellationToken).T 'DevElf\.Threading\.RateLimiting\.RateLimiterExtensions\.ApplyToAsync\\(this System\.Threading\.RateLimiting\.RateLimiter, System\.Func\\>, int, System\.Nullable\, System\.TimeProvider, System\.Threading\.CancellationToken\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1 'System\.Threading\.Tasks\.Task\`1')[>](https://learn.microsoft.com/en-us/dotnet/api/system.func-2 'System\.Func\`2') + +The request function to execute once permits are acquired\. + + + +`permitCount` [System\.Int32](https://learn.microsoft.com/en-us/dotnet/api/system.int32 'System\.Int32') + +The number of permits needed to execute the request\. Must be positive\. +Defaults to 1\. + + + +`idleTime` [System\.Nullable<](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[System\.TimeSpan](https://learn.microsoft.com/en-us/dotnet/api/system.timespan 'System\.TimeSpan')[>](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') + +The time to wait between permit acquisition attempts when permits are not +immediately available\. When [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null'), defaults to 100 +microseconds\. This prevents busy\-waiting while allowing responsive permit +acquisition\. + + + +`timeProvider` [System\.TimeProvider](https://learn.microsoft.com/en-us/dotnet/api/system.timeprovider 'System\.TimeProvider') + +The [System\.TimeProvider](https://learn.microsoft.com/en-us/dotnet/api/system.timeprovider 'System\.TimeProvider') to use for time\-based operations during idle +waits\. When [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null'), defaults to [System\.TimeProvider\.System](https://learn.microsoft.com/en-us/dotnet/api/system.timeprovider.system 'System\.TimeProvider\.System')\. + + + +`cancellationToken` [System\.Threading\.CancellationToken](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken 'System\.Threading\.CancellationToken') + +A token to monitor for cancellation requests during permit acquisition and +request execution\. + +#### Returns +[System\.Threading\.Tasks\.Task<](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1 'System\.Threading\.Tasks\.Task\`1')[T](RateLimiterExtensions.md#DevElf.Threading.RateLimiting.RateLimiterExtensions.ApplyToAsync_T_(thisSystem.Threading.RateLimiting.RateLimiter,System.Func_System.Threading.CancellationToken,System.Threading.Tasks.Task_T__,int,System.Nullable_System.TimeSpan_,System.TimeProvider,System.Threading.CancellationToken).T 'DevElf\.Threading\.RateLimiting\.RateLimiterExtensions\.ApplyToAsync\\(this System\.Threading\.RateLimiting\.RateLimiter, System\.Func\\>, int, System\.Nullable\, System\.TimeProvider, System\.Threading\.CancellationToken\)\.T')[>](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1 'System\.Threading\.Tasks\.Task\`1') +A task that represents the asynchronous operation\. The task result contains +the value returned by the request function\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +If [limiter](RateLimiterExtensions.md#DevElf.Threading.RateLimiting.RateLimiterExtensions.ApplyToAsync_T_(thisSystem.Threading.RateLimiting.RateLimiter,System.Func_System.Threading.CancellationToken,System.Threading.Tasks.Task_T__,int,System.Nullable_System.TimeSpan_,System.TimeProvider,System.Threading.CancellationToken).limiter 'DevElf\.Threading\.RateLimiting\.RateLimiterExtensions\.ApplyToAsync\\(this System\.Threading\.RateLimiting\.RateLimiter, System\.Func\\>, int, System\.Nullable\, System\.TimeProvider, System\.Threading\.CancellationToken\)\.limiter') or [request](RateLimiterExtensions.md#DevElf.Threading.RateLimiting.RateLimiterExtensions.ApplyToAsync_T_(thisSystem.Threading.RateLimiting.RateLimiter,System.Func_System.Threading.CancellationToken,System.Threading.Tasks.Task_T__,int,System.Nullable_System.TimeSpan_,System.TimeProvider,System.Threading.CancellationToken).request 'DevElf\.Threading\.RateLimiting\.RateLimiterExtensions\.ApplyToAsync\\(this System\.Threading\.RateLimiting\.RateLimiter, System\.Func\\>, int, System\.Nullable\, System\.TimeProvider, System\.Threading\.CancellationToken\)\.request') is +[null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + +[System\.OperationCanceledException](https://learn.microsoft.com/en-us/dotnet/api/system.operationcanceledexception 'System\.OperationCanceledException') +If the [cancellationToken](RateLimiterExtensions.md#DevElf.Threading.RateLimiting.RateLimiterExtensions.ApplyToAsync_T_(thisSystem.Threading.RateLimiting.RateLimiter,System.Func_System.Threading.CancellationToken,System.Threading.Tasks.Task_T__,int,System.Nullable_System.TimeSpan_,System.TimeProvider,System.Threading.CancellationToken).cancellationToken 'DevElf\.Threading\.RateLimiting\.RateLimiterExtensions\.ApplyToAsync\\(this System\.Threading\.RateLimiting\.RateLimiter, System\.Func\\>, int, System\.Nullable\, System\.TimeProvider, System\.Threading\.CancellationToken\)\.cancellationToken') is canceled before or during +execution\. + +### Example + +```csharp +var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions +{ + PermitLimit = 5, + QueueLimit = 10 +}); + +var response = await limiter.ApplyToAsync( + async ct => await httpClient.GetAsync(url, ct), + permitCount: 1, + cancellationToken: cancellationToken); +``` + +### Remarks + +This method repeatedly attempts to acquire the specified number of permits. +If permits are not immediately available, it waits for the specified +[idleTime](RateLimiterExtensions.md#DevElf.Threading.RateLimiting.RateLimiterExtensions.ApplyToAsync_T_(thisSystem.Threading.RateLimiting.RateLimiter,System.Func_System.Threading.CancellationToken,System.Threading.Tasks.Task_T__,int,System.Nullable_System.TimeSpan_,System.TimeProvider,System.Threading.CancellationToken).idleTime 'DevElf\.Threading\.RateLimiting\.RateLimiterExtensions\.ApplyToAsync\\(this System\.Threading\.RateLimiting\.RateLimiter, System\.Func\\>, int, System\.Nullable\, System\.TimeProvider, System\.Threading\.CancellationToken\)\.idleTime') before trying again. Once permits are acquired, +the request is executed and the permits are automatically released. + +The lease is properly disposed even if the request throws an exception, +ensuring permits are returned to the limiter. \ No newline at end of file diff --git a/docs/api/DevElf/RateLimiterExtensions.md b/docs/api/DevElf/RateLimiterExtensions.md new file mode 100644 index 0000000..adf9583 --- /dev/null +++ b/docs/api/DevElf/RateLimiterExtensions.md @@ -0,0 +1,18 @@ +#### [DevElf](README.md 'README') +### [DevElf\.Threading\.RateLimiting](DevElf.Threading.RateLimiting.md 'DevElf\.Threading\.RateLimiting') + +## RateLimiterExtensions Class + +Provides extension methods for [System\.Threading\.RateLimiting\.RateLimiter](https://learn.microsoft.com/en-us/dotnet/api/system.threading.ratelimiting.ratelimiter 'System\.Threading\.RateLimiting\.RateLimiter') to simplify applying +rate limiting to actions and requests\. + +```csharp +public static class RateLimiterExtensions +``` + +Inheritance [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') 🡒 RateLimiterExtensions + +| Methods | | +| :--- | :--- | +| [ApplyToAsync\(this RateLimiter, Func<CancellationToken,Task>, int, Nullable<TimeSpan>, TimeProvider, CancellationToken\)](RateLimiterExtensions.ApplyToAsync.md#DevElf.Threading.RateLimiting.RateLimiterExtensions.ApplyToAsync(thisSystem.Threading.RateLimiting.RateLimiter,System.Func_System.Threading.CancellationToken,System.Threading.Tasks.Task_,int,System.Nullable_System.TimeSpan_,System.TimeProvider,System.Threading.CancellationToken) 'DevElf\.Threading\.RateLimiting\.RateLimiterExtensions\.ApplyToAsync\(this System\.Threading\.RateLimiting\.RateLimiter, System\.Func\, int, System\.Nullable\, System\.TimeProvider, System\.Threading\.CancellationToken\)') | Applies rate limiting to an asynchronous action, automatically acquiring and releasing permits\. | +| [ApplyToAsync<T>\(this RateLimiter, Func<CancellationToken,Task<T>>, int, Nullable<TimeSpan>, TimeProvider, CancellationToken\)](RateLimiterExtensions.ApplyToAsync.md#DevElf.Threading.RateLimiting.RateLimiterExtensions.ApplyToAsync_T_(thisSystem.Threading.RateLimiting.RateLimiter,System.Func_System.Threading.CancellationToken,System.Threading.Tasks.Task_T__,int,System.Nullable_System.TimeSpan_,System.TimeProvider,System.Threading.CancellationToken) 'DevElf\.Threading\.RateLimiting\.RateLimiterExtensions\.ApplyToAsync\\(this System\.Threading\.RateLimiting\.RateLimiter, System\.Func\\>, int, System\.Nullable\, System\.TimeProvider, System\.Threading\.CancellationToken\)') | Applies rate limiting to an asynchronous request, automatically acquiring and releasing permits, and returns the result\. | diff --git a/docs/api/DevElf/ServiceCollectionExtensions.Add.md b/docs/api/DevElf/ServiceCollectionExtensions.Add.md new file mode 100644 index 0000000..20cf4df --- /dev/null +++ b/docs/api/DevElf/ServiceCollectionExtensions.Add.md @@ -0,0 +1,166 @@ +#### [DevElf](README.md 'README') +### [DevElf\.DependencyInjection](DevElf.DependencyInjection.md 'DevElf\.DependencyInjection').[ServiceCollectionExtensions](ServiceCollectionExtensions.md 'DevElf\.DependencyInjection\.ServiceCollectionExtensions') + +## ServiceCollectionExtensions\.Add Method + +| Overloads | | +| :--- | :--- | +| [Add<TService,TImplementation>\(this IServiceCollection, ServiceLifetime\)](ServiceCollectionExtensions.Add.md#DevElf.DependencyInjection.ServiceCollectionExtensions.Add_TService,TImplementation_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.Add\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Registers a service of type [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.Add_TService,TImplementation_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.Add\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService') with an implementation type of [TImplementation](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.Add_TService,TImplementation_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TImplementation 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.Add\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TImplementation') using the specified lifetime\. | +| [Add<TService>\(this IServiceCollection, ServiceLifetime\)](ServiceCollectionExtensions.Add.md#DevElf.DependencyInjection.ServiceCollectionExtensions.Add_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.Add\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Registers a service of type [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.Add_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.Add\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService') with itself as the implementation type using the specified lifetime\. | +| [Add<TService>\(this IServiceCollection, Func<IServiceProvider,TService>, ServiceLifetime\)](ServiceCollectionExtensions.Add.md#DevElf.DependencyInjection.ServiceCollectionExtensions.Add_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.Add\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Registers a service of type [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.Add_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.Add\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService') using a factory function with the specified lifetime\. | + + + +## ServiceCollectionExtensions\.Add\\(this IServiceCollection, ServiceLifetime\) Method + +Registers a service of type [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.Add_TService,TImplementation_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.Add\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService') with an implementation type +of [TImplementation](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.Add_TService,TImplementation_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TImplementation 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.Add\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TImplementation') using the specified lifetime\. + +```csharp +public static Microsoft.Extensions.DependencyInjection.IServiceCollection Add(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, Microsoft.Extensions.DependencyInjection.ServiceLifetime lifetime) + where TService : class + where TImplementation : TService; +``` +#### Type parameters + + + +`TService` + +The service type to register\. Must be a class\. + + + +`TImplementation` + +The implementation type that implements [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.Add_TService,TImplementation_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.Add\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService')\. +#### Parameters + + + +`services` [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') + +The [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') to add the service to\. + + + +`lifetime` [Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.servicelifetime 'Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime') + +The lifetime of the service\. + +#### Returns +[Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') +The same [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') for chaining\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +[services](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.Add_TService,TImplementation_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).services 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.Add\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.services') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + +### Example + +```csharp +services.Add(ServiceLifetime.Singleton); +``` + + + +## ServiceCollectionExtensions\.Add\\(this IServiceCollection, ServiceLifetime\) Method + +Registers a service of type [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.Add_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.Add\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService') with itself as the implementation +type using the specified lifetime\. + +```csharp +public static Microsoft.Extensions.DependencyInjection.IServiceCollection Add(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, Microsoft.Extensions.DependencyInjection.ServiceLifetime lifetime) + where TService : class; +``` +#### Type parameters + + + +`TService` + +The type of service to register\. Must be a class\. +#### Parameters + + + +`services` [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') + +The [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') to add the service to\. + + + +`lifetime` [Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.servicelifetime 'Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime') + +The lifetime of the service\. + +#### Returns +[Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') +The same [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') for chaining\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +[services](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.Add_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).services 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.Add\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.services') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + +### Example + +```csharp +services.Add(ServiceLifetime.Transient); +``` + + + +## ServiceCollectionExtensions\.Add\\(this IServiceCollection, Func\, ServiceLifetime\) Method + +Registers a service of type [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.Add_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.Add\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService') using a factory function +with the specified lifetime\. + +```csharp +public static Microsoft.Extensions.DependencyInjection.IServiceCollection Add(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Func serviceFactory, Microsoft.Extensions.DependencyInjection.ServiceLifetime lifetime) + where TService : class; +``` +#### Type parameters + + + +`TService` + +The type of service to register\. Must be a class\. +#### Parameters + + + +`services` [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') + +The [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') to add the service to\. + + + +`serviceFactory` [System\.Func<](https://learn.microsoft.com/en-us/dotnet/api/system.func-2 'System\.Func\`2')[System\.IServiceProvider](https://learn.microsoft.com/en-us/dotnet/api/system.iserviceprovider 'System\.IServiceProvider')[,](https://learn.microsoft.com/en-us/dotnet/api/system.func-2 'System\.Func\`2')[TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.Add_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.Add\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService')[>](https://learn.microsoft.com/en-us/dotnet/api/system.func-2 'System\.Func\`2') + +The factory function that creates instances of the service\. + + + +`lifetime` [Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.servicelifetime 'Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime') + +The lifetime of the service\. + +#### Returns +[Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') +The same [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') for chaining\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +[services](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.Add_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).services 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.Add\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.services') or [serviceFactory](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.Add_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).serviceFactory 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.Add\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.serviceFactory') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + +### Example + +```csharp +services.Add( + sp => new MyService(sp.GetRequiredService()), + ServiceLifetime.Scoped); +``` \ No newline at end of file diff --git a/docs/api/DevElf/ServiceCollectionExtensions.AddFactoryFunc.md b/docs/api/DevElf/ServiceCollectionExtensions.AddFactoryFunc.md new file mode 100644 index 0000000..a93e7e7 --- /dev/null +++ b/docs/api/DevElf/ServiceCollectionExtensions.AddFactoryFunc.md @@ -0,0 +1,122 @@ +#### [DevElf](README.md 'README') +### [DevElf\.DependencyInjection](DevElf.DependencyInjection.md 'DevElf\.DependencyInjection').[ServiceCollectionExtensions](ServiceCollectionExtensions.md 'DevElf\.DependencyInjection\.ServiceCollectionExtensions') + +## ServiceCollectionExtensions\.AddFactoryFunc Method + +| Overloads | | +| :--- | :--- | +| [AddFactoryFunc<TService>\(this IServiceCollection, ServiceLifetime\)](ServiceCollectionExtensions.AddFactoryFunc.md#DevElf.DependencyInjection.ServiceCollectionExtensions.AddFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.AddFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Registers a factory function \([System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\) with the specified lifetime that resolves instances of [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.AddFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.AddFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService') from the service provider\. | +| [AddFactoryFunc<TService>\(this IServiceCollection, Func<IServiceProvider,TService>, ServiceLifetime\)](ServiceCollectionExtensions.AddFactoryFunc.md#DevElf.DependencyInjection.ServiceCollectionExtensions.AddFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.AddFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Registers a factory function \([System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\) with the specified lifetime that wraps a custom service factory for creating instances of [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.AddFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.AddFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService')\. | + + + +## ServiceCollectionExtensions\.AddFactoryFunc\\(this IServiceCollection, ServiceLifetime\) Method + +Registers a factory function \([System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\) with the specified lifetime +that resolves instances of [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.AddFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.AddFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService') from the service provider\. + +```csharp +public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddFactoryFunc(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, Microsoft.Extensions.DependencyInjection.ServiceLifetime factoryLifetime) + where TService : class; +``` +#### Type parameters + + + +`TService` + +The type of service the factory will create\. Must be a class\. +#### Parameters + + + +`services` [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') + +The [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') to add the factory to\. + + + +`factoryLifetime` [Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.servicelifetime 'Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime') + +The lifetime of the factory function itself\. + +#### Returns +[Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') +The same [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') for chaining\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +[services](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.AddFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).services 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.AddFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.services') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + +### Example + +```csharp +services.AddScoped(); +services.AddFactoryFunc(ServiceLifetime.Singleton); + +// Later, inject Func to create instances on demand +``` + +### Remarks +The factory function calls [Microsoft\.Extensions\.DependencyInjection\.ServiceProviderServiceExtensions\.GetRequiredService<>\.IServiceProvider\)](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.serviceproviderserviceextensions.getrequiredservice--1#microsoft-extensions-dependencyinjection-serviceproviderserviceextensions-getrequiredservice--1(system-iserviceprovider) 'Microsoft\.Extensions\.DependencyInjection\.ServiceProviderServiceExtensions\.GetRequiredService\`\`1\(System\.IServiceProvider\)') +to resolve the service when invoked\. The service itself must be registered separately\. + + + +## ServiceCollectionExtensions\.AddFactoryFunc\\(this IServiceCollection, Func\, ServiceLifetime\) Method + +Registers a factory function \([System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\) with the specified lifetime +that wraps a custom service factory for creating instances of [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.AddFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.AddFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService')\. + +```csharp +public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddFactoryFunc(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Func serviceFactory, Microsoft.Extensions.DependencyInjection.ServiceLifetime factoryLifetime) + where TService : class; +``` +#### Type parameters + + + +`TService` + +The type of service the factory will create\. Must be a class\. +#### Parameters + + + +`services` [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') + +The [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') to add the factory to\. + + + +`serviceFactory` [System\.Func<](https://learn.microsoft.com/en-us/dotnet/api/system.func-2 'System\.Func\`2')[System\.IServiceProvider](https://learn.microsoft.com/en-us/dotnet/api/system.iserviceprovider 'System\.IServiceProvider')[,](https://learn.microsoft.com/en-us/dotnet/api/system.func-2 'System\.Func\`2')[TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.AddFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.AddFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService')[>](https://learn.microsoft.com/en-us/dotnet/api/system.func-2 'System\.Func\`2') + +The factory function that creates instances of the service\. + + + +`factoryLifetime` [Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.servicelifetime 'Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime') + +The lifetime of the factory function itself\. + +#### Returns +[Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') +The same [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') for chaining\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +[services](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.AddFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).services 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.AddFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.services') or [serviceFactory](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.AddFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).serviceFactory 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.AddFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.serviceFactory') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + +### Example + +```csharp +services.AddFactoryFunc( + sp => new MyService(sp.GetRequiredService()), + ServiceLifetime.Singleton); +``` + +### Remarks +This overload wraps the provided [serviceFactory](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.AddFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).serviceFactory 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.AddFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.serviceFactory') in a parameter\-less function +that can be injected as [System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\. \ No newline at end of file diff --git a/docs/api/DevElf/ServiceCollectionExtensions.AddWithFactoryFunc.md b/docs/api/DevElf/ServiceCollectionExtensions.AddWithFactoryFunc.md new file mode 100644 index 0000000..111d23c --- /dev/null +++ b/docs/api/DevElf/ServiceCollectionExtensions.AddWithFactoryFunc.md @@ -0,0 +1,176 @@ +#### [DevElf](README.md 'README') +### [DevElf\.DependencyInjection](DevElf.DependencyInjection.md 'DevElf\.DependencyInjection').[ServiceCollectionExtensions](ServiceCollectionExtensions.md 'DevElf\.DependencyInjection\.ServiceCollectionExtensions') + +## ServiceCollectionExtensions\.AddWithFactoryFunc Method + +| Overloads | | +| :--- | :--- | +| [AddWithFactoryFunc<TService,TImplementation>\(this IServiceCollection, ServiceLifetime\)](ServiceCollectionExtensions.AddWithFactoryFunc.md#DevElf.DependencyInjection.ServiceCollectionExtensions.AddWithFactoryFunc_TService,TImplementation_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.AddWithFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Registers a service with its implementation type using the specified lifetime and also registers a factory function \([System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\) that can be injected to create instances on demand\. | +| [AddWithFactoryFunc<TService>\(this IServiceCollection, ServiceLifetime\)](ServiceCollectionExtensions.AddWithFactoryFunc.md#DevElf.DependencyInjection.ServiceCollectionExtensions.AddWithFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.AddWithFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Registers a service with the specified lifetime and also registers a factory function \([System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\) that can be injected to create instances on demand\. | +| [AddWithFactoryFunc<TService>\(this IServiceCollection, Func<IServiceProvider,TService>, ServiceLifetime\)](ServiceCollectionExtensions.AddWithFactoryFunc.md#DevElf.DependencyInjection.ServiceCollectionExtensions.AddWithFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.AddWithFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Registers a service using a factory function with the specified lifetime and also registers a factory function \([System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\) that can be injected to create instances on demand\. | + + + +## ServiceCollectionExtensions\.AddWithFactoryFunc\\(this IServiceCollection, ServiceLifetime\) Method + +Registers a service with its implementation type using the specified lifetime and also registers +a factory function \([System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\) that can be injected to create instances on demand\. + +```csharp +public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddWithFactoryFunc(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, Microsoft.Extensions.DependencyInjection.ServiceLifetime serviceLifetime) + where TService : class + where TImplementation : TService; +``` +#### Type parameters + + + +`TService` + +The service type to register\. Must be a class\. + + + +`TImplementation` + +The implementation type that implements [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.AddWithFactoryFunc_TService,TImplementation_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.AddWithFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService')\. +#### Parameters + + + +`services` [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') + +The [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') to add the services to\. + + + +`serviceLifetime` [Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.servicelifetime 'Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime') + +The lifetime of the service\. + +#### Returns +[Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') +The same [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') for chaining\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +[services](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.AddWithFactoryFunc_TService,TImplementation_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).services 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.AddWithFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.services') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + +### Example + +```csharp +services.AddWithFactoryFunc(ServiceLifetime.Singleton); +``` + + + +## ServiceCollectionExtensions\.AddWithFactoryFunc\\(this IServiceCollection, ServiceLifetime\) Method + +Registers a service with the specified lifetime and also registers a factory function +\([System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\) that can be injected to create instances on demand\. + +```csharp +public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddWithFactoryFunc(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, Microsoft.Extensions.DependencyInjection.ServiceLifetime serviceLifetime) + where TService : class; +``` +#### Type parameters + + + +`TService` + +The type of service to register\. Must be a class\. +#### Parameters + + + +`services` [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') + +The [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') to add the services to\. + + + +`serviceLifetime` [Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.servicelifetime 'Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime') + +The lifetime of the service\. + +#### Returns +[Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') +The same [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') for chaining\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +[services](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.AddWithFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).services 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.AddWithFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.services') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + +### Example + +```csharp +services.AddWithFactoryFunc(ServiceLifetime.Scoped); + +// Later, inject Func to create instances on demand: +public class Consumer(Func serviceFactory) +{ + public void DoWork() + { + var service = serviceFactory(); + // use service... + } +} +``` + + + +## ServiceCollectionExtensions\.AddWithFactoryFunc\\(this IServiceCollection, Func\, ServiceLifetime\) Method + +Registers a service using a factory function with the specified lifetime and also registers +a factory function \([System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\) that can be injected to create instances on demand\. + +```csharp +public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddWithFactoryFunc(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Func serviceFactory, Microsoft.Extensions.DependencyInjection.ServiceLifetime serviceLifetime) + where TService : class; +``` +#### Type parameters + + + +`TService` + +The type of service to register\. Must be a class\. +#### Parameters + + + +`services` [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') + +The [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') to add the services to\. + + + +`serviceFactory` [System\.Func<](https://learn.microsoft.com/en-us/dotnet/api/system.func-2 'System\.Func\`2')[System\.IServiceProvider](https://learn.microsoft.com/en-us/dotnet/api/system.iserviceprovider 'System\.IServiceProvider')[,](https://learn.microsoft.com/en-us/dotnet/api/system.func-2 'System\.Func\`2')[TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.AddWithFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.AddWithFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService')[>](https://learn.microsoft.com/en-us/dotnet/api/system.func-2 'System\.Func\`2') + +The factory function that creates instances of the service\. + + + +`serviceLifetime` [Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.servicelifetime 'Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime') + +The lifetime of the service\. + +#### Returns +[Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') +The same [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') for chaining\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +[services](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.AddWithFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).services 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.AddWithFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.services') or [serviceFactory](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.AddWithFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).serviceFactory 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.AddWithFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.serviceFactory') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + +### Example + +```csharp +services.AddWithFactoryFunc( + sp => new MyService(sp.GetRequiredService()), + ServiceLifetime.Transient); +``` \ No newline at end of file diff --git a/docs/api/DevElf/ServiceCollectionExtensions.TryAdd.md b/docs/api/DevElf/ServiceCollectionExtensions.TryAdd.md new file mode 100644 index 0000000..599e6e6 --- /dev/null +++ b/docs/api/DevElf/ServiceCollectionExtensions.TryAdd.md @@ -0,0 +1,158 @@ +#### [DevElf](README.md 'README') +### [DevElf\.DependencyInjection](DevElf.DependencyInjection.md 'DevElf\.DependencyInjection').[ServiceCollectionExtensions](ServiceCollectionExtensions.md 'DevElf\.DependencyInjection\.ServiceCollectionExtensions') + +## ServiceCollectionExtensions\.TryAdd Method + +| Overloads | | +| :--- | :--- | +| [TryAdd<TService,TImplementation>\(this IServiceCollection, ServiceLifetime\)](ServiceCollectionExtensions.TryAdd.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAdd_TService,TImplementation_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAdd\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Tries to register a service of type [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAdd_TService,TImplementation_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAdd\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService') with an implementation type of [TImplementation](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAdd_TService,TImplementation_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TImplementation 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAdd\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TImplementation') using the specified lifetime, if not already registered\. | +| [TryAdd<TService>\(this IServiceCollection, ServiceLifetime\)](ServiceCollectionExtensions.TryAdd.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAdd_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAdd\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Tries to register a service of type [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAdd_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAdd\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService') with itself as the implementation type using the specified lifetime, if not already registered\. | +| [TryAdd<TService>\(this IServiceCollection, Func<IServiceProvider,TService>, ServiceLifetime\)](ServiceCollectionExtensions.TryAdd.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAdd_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAdd\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Tries to register a service of type [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAdd_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAdd\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService') using a factory function with the specified lifetime, if not already registered\. | + + + +## ServiceCollectionExtensions\.TryAdd\\(this IServiceCollection, ServiceLifetime\) Method + +Tries to register a service of type [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAdd_TService,TImplementation_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAdd\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService') with an implementation type +of [TImplementation](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAdd_TService,TImplementation_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TImplementation 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAdd\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TImplementation') using the specified lifetime, if not already registered\. + +```csharp +public static Microsoft.Extensions.DependencyInjection.IServiceCollection TryAdd(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, Microsoft.Extensions.DependencyInjection.ServiceLifetime lifetime) + where TService : class + where TImplementation : TService; +``` +#### Type parameters + + + +`TService` + +The service type to register\. Must be a class\. + + + +`TImplementation` + +The implementation type that implements [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAdd_TService,TImplementation_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAdd\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService')\. +#### Parameters + + + +`services` [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') + +The [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') to add the service to\. + + + +`lifetime` [Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.servicelifetime 'Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime') + +The lifetime of the service\. + +#### Returns +[Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') +The same [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') for chaining\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +[services](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAdd_TService,TImplementation_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).services 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAdd\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.services') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + +### Remarks +This method only registers the service if no service of type [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAdd_TService,TImplementation_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAdd\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService') +has been registered yet\. + + + +## ServiceCollectionExtensions\.TryAdd\\(this IServiceCollection, ServiceLifetime\) Method + +Tries to register a service of type [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAdd_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAdd\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService') with itself as the implementation +type using the specified lifetime, if not already registered\. + +```csharp +public static Microsoft.Extensions.DependencyInjection.IServiceCollection TryAdd(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, Microsoft.Extensions.DependencyInjection.ServiceLifetime lifetime) + where TService : class; +``` +#### Type parameters + + + +`TService` + +The type of service to register\. Must be a class\. +#### Parameters + + + +`services` [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') + +The [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') to add the service to\. + + + +`lifetime` [Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.servicelifetime 'Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime') + +The lifetime of the service\. + +#### Returns +[Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') +The same [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') for chaining\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +[services](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAdd_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).services 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAdd\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.services') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + +### Remarks +This method only registers the service if no service of type [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAdd_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAdd\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService') +has been registered yet\. + + + +## ServiceCollectionExtensions\.TryAdd\\(this IServiceCollection, Func\, ServiceLifetime\) Method + +Tries to register a service of type [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAdd_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAdd\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService') using a factory function +with the specified lifetime, if not already registered\. + +```csharp +public static Microsoft.Extensions.DependencyInjection.IServiceCollection TryAdd(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Func serviceFactory, Microsoft.Extensions.DependencyInjection.ServiceLifetime lifetime) + where TService : class; +``` +#### Type parameters + + + +`TService` + +The type of service to register\. Must be a class\. +#### Parameters + + + +`services` [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') + +The [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') to add the service to\. + + + +`serviceFactory` [System\.Func<](https://learn.microsoft.com/en-us/dotnet/api/system.func-2 'System\.Func\`2')[System\.IServiceProvider](https://learn.microsoft.com/en-us/dotnet/api/system.iserviceprovider 'System\.IServiceProvider')[,](https://learn.microsoft.com/en-us/dotnet/api/system.func-2 'System\.Func\`2')[TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAdd_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAdd\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService')[>](https://learn.microsoft.com/en-us/dotnet/api/system.func-2 'System\.Func\`2') + +The factory function that creates instances of the service\. + + + +`lifetime` [Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.servicelifetime 'Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime') + +The lifetime of the service\. + +#### Returns +[Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') +The same [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') for chaining\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +[services](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAdd_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).services 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAdd\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.services') or [serviceFactory](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAdd_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).serviceFactory 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAdd\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.serviceFactory') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + +### Remarks +This method only registers the service if no service of type [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAdd_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAdd\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService') +has been registered yet\. \ No newline at end of file diff --git a/docs/api/DevElf/ServiceCollectionExtensions.TryAddFactoryFunc.md b/docs/api/DevElf/ServiceCollectionExtensions.TryAddFactoryFunc.md new file mode 100644 index 0000000..4a5012b --- /dev/null +++ b/docs/api/DevElf/ServiceCollectionExtensions.TryAddFactoryFunc.md @@ -0,0 +1,105 @@ +#### [DevElf](README.md 'README') +### [DevElf\.DependencyInjection](DevElf.DependencyInjection.md 'DevElf\.DependencyInjection').[ServiceCollectionExtensions](ServiceCollectionExtensions.md 'DevElf\.DependencyInjection\.ServiceCollectionExtensions') + +## ServiceCollectionExtensions\.TryAddFactoryFunc Method + +| Overloads | | +| :--- | :--- | +| [TryAddFactoryFunc<TService>\(this IServiceCollection, ServiceLifetime\)](ServiceCollectionExtensions.TryAddFactoryFunc.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAddFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAddFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Tries to register a factory function \([System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\) with the specified lifetime \(if not already registered\) that resolves instances of [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAddFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAddFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService') from the service provider\. | +| [TryAddFactoryFunc<TService>\(this IServiceCollection, Func<IServiceProvider,TService>, ServiceLifetime\)](ServiceCollectionExtensions.TryAddFactoryFunc.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAddFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAddFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Tries to register a factory function \([System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\) with the specified lifetime \(if not already registered\) that wraps a custom service factory for creating instances of [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAddFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAddFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService')\. | + + + +## ServiceCollectionExtensions\.TryAddFactoryFunc\\(this IServiceCollection, ServiceLifetime\) Method + +Tries to register a factory function \([System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\) with the specified lifetime +\(if not already registered\) that resolves instances of [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAddFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAddFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService') from the service provider\. + +```csharp +public static Microsoft.Extensions.DependencyInjection.IServiceCollection TryAddFactoryFunc(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, Microsoft.Extensions.DependencyInjection.ServiceLifetime factoryLifetime) + where TService : class; +``` +#### Type parameters + + + +`TService` + +The type of service the factory will create\. Must be a class\. +#### Parameters + + + +`services` [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') + +The [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') to add the factory to\. + + + +`factoryLifetime` [Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.servicelifetime 'Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime') + +The lifetime of the factory function itself\. + +#### Returns +[Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') +The same [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') for chaining\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +[services](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAddFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).services 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAddFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.services') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + +### Remarks +This method only registers the factory if no factory of type [System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1') +has been registered yet\. + + + +## ServiceCollectionExtensions\.TryAddFactoryFunc\\(this IServiceCollection, Func\, ServiceLifetime\) Method + +Tries to register a factory function \([System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\) with the specified lifetime +\(if not already registered\) that wraps a custom service factory for creating instances of [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAddFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAddFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService')\. + +```csharp +public static Microsoft.Extensions.DependencyInjection.IServiceCollection TryAddFactoryFunc(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Func serviceFactory, Microsoft.Extensions.DependencyInjection.ServiceLifetime factoryLifetime) + where TService : class; +``` +#### Type parameters + + + +`TService` + +The type of service the factory will create\. Must be a class\. +#### Parameters + + + +`services` [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') + +The [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') to add the factory to\. + + + +`serviceFactory` [System\.Func<](https://learn.microsoft.com/en-us/dotnet/api/system.func-2 'System\.Func\`2')[System\.IServiceProvider](https://learn.microsoft.com/en-us/dotnet/api/system.iserviceprovider 'System\.IServiceProvider')[,](https://learn.microsoft.com/en-us/dotnet/api/system.func-2 'System\.Func\`2')[TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAddFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAddFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService')[>](https://learn.microsoft.com/en-us/dotnet/api/system.func-2 'System\.Func\`2') + +The factory function that creates instances of the service\. + + + +`factoryLifetime` [Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.servicelifetime 'Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime') + +The lifetime of the factory function itself\. + +#### Returns +[Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') +The same [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') for chaining\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +[services](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAddFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).services 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAddFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.services') or [serviceFactory](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAddFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).serviceFactory 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAddFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.serviceFactory') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + +### Remarks +This method only registers the factory if no factory of type [System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1') +has been registered yet\. \ No newline at end of file diff --git a/docs/api/DevElf/ServiceCollectionExtensions.TryAddWithFactoryFunc.md b/docs/api/DevElf/ServiceCollectionExtensions.TryAddWithFactoryFunc.md new file mode 100644 index 0000000..fa457e7 --- /dev/null +++ b/docs/api/DevElf/ServiceCollectionExtensions.TryAddWithFactoryFunc.md @@ -0,0 +1,161 @@ +#### [DevElf](README.md 'README') +### [DevElf\.DependencyInjection](DevElf.DependencyInjection.md 'DevElf\.DependencyInjection').[ServiceCollectionExtensions](ServiceCollectionExtensions.md 'DevElf\.DependencyInjection\.ServiceCollectionExtensions') + +## ServiceCollectionExtensions\.TryAddWithFactoryFunc Method + +| Overloads | | +| :--- | :--- | +| [TryAddWithFactoryFunc<TService,TImplementation>\(this IServiceCollection, ServiceLifetime\)](ServiceCollectionExtensions.TryAddWithFactoryFunc.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAddWithFactoryFunc_TService,TImplementation_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAddWithFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Tries to register a service with its implementation type using the specified lifetime \(if not already registered\) and also registers a factory function \([System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\) that can be injected to create instances on demand\. | +| [TryAddWithFactoryFunc<TService>\(this IServiceCollection, ServiceLifetime\)](ServiceCollectionExtensions.TryAddWithFactoryFunc.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAddWithFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAddWithFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Tries to register a service with the specified lifetime \(if not already registered\) and also registers a factory function \([System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\) that can be injected to create instances on demand\. | +| [TryAddWithFactoryFunc<TService>\(this IServiceCollection, Func<IServiceProvider,TService>, ServiceLifetime\)](ServiceCollectionExtensions.TryAddWithFactoryFunc.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAddWithFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAddWithFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Tries to register a service using a factory function with the specified lifetime \(if not already registered\) and also registers a factory function \([System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\) that can be injected to create instances on demand\. | + + + +## ServiceCollectionExtensions\.TryAddWithFactoryFunc\\(this IServiceCollection, ServiceLifetime\) Method + +Tries to register a service with its implementation type using the specified lifetime +\(if not already registered\) and also registers a factory function \([System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\) +that can be injected to create instances on demand\. + +```csharp +public static Microsoft.Extensions.DependencyInjection.IServiceCollection TryAddWithFactoryFunc(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, Microsoft.Extensions.DependencyInjection.ServiceLifetime serviceLifetime) + where TService : class + where TImplementation : TService; +``` +#### Type parameters + + + +`TService` + +The service type to register\. Must be a class\. + + + +`TImplementation` + +The implementation type that implements [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAddWithFactoryFunc_TService,TImplementation_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAddWithFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService')\. +#### Parameters + + + +`services` [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') + +The [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') to add the services to\. + + + +`serviceLifetime` [Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.servicelifetime 'Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime') + +The lifetime of the service\. + +#### Returns +[Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') +The same [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') for chaining\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +[services](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAddWithFactoryFunc_TService,TImplementation_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).services 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAddWithFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.services') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + +### Remarks +This method only registers the service if no service of type [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAddWithFactoryFunc_TService,TImplementation_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAddWithFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService') +has been registered yet\. The factory function is also registered only if not already present\. + + + +## ServiceCollectionExtensions\.TryAddWithFactoryFunc\\(this IServiceCollection, ServiceLifetime\) Method + +Tries to register a service with the specified lifetime \(if not already registered\) and also +registers a factory function \([System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\) that can be injected to create +instances on demand\. + +```csharp +public static Microsoft.Extensions.DependencyInjection.IServiceCollection TryAddWithFactoryFunc(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, Microsoft.Extensions.DependencyInjection.ServiceLifetime serviceLifetime) + where TService : class; +``` +#### Type parameters + + + +`TService` + +The type of service to register\. Must be a class\. +#### Parameters + + + +`services` [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') + +The [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') to add the services to\. + + + +`serviceLifetime` [Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.servicelifetime 'Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime') + +The lifetime of the service\. + +#### Returns +[Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') +The same [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') for chaining\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +[services](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAddWithFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).services 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAddWithFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.services') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + +### Remarks +This method only registers the service if no service of type [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAddWithFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAddWithFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService') +has been registered yet\. The factory function is also registered only if not already present\. + + + +## ServiceCollectionExtensions\.TryAddWithFactoryFunc\\(this IServiceCollection, Func\, ServiceLifetime\) Method + +Tries to register a service using a factory function with the specified lifetime +\(if not already registered\) and also registers a factory function \([System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\) +that can be injected to create instances on demand\. + +```csharp +public static Microsoft.Extensions.DependencyInjection.IServiceCollection TryAddWithFactoryFunc(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Func serviceFactory, Microsoft.Extensions.DependencyInjection.ServiceLifetime serviceLifetime) + where TService : class; +``` +#### Type parameters + + + +`TService` + +The type of service to register\. Must be a class\. +#### Parameters + + + +`services` [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') + +The [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') to add the services to\. + + + +`serviceFactory` [System\.Func<](https://learn.microsoft.com/en-us/dotnet/api/system.func-2 'System\.Func\`2')[System\.IServiceProvider](https://learn.microsoft.com/en-us/dotnet/api/system.iserviceprovider 'System\.IServiceProvider')[,](https://learn.microsoft.com/en-us/dotnet/api/system.func-2 'System\.Func\`2')[TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAddWithFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAddWithFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService')[>](https://learn.microsoft.com/en-us/dotnet/api/system.func-2 'System\.Func\`2') + +The factory function that creates instances of the service\. + + + +`serviceLifetime` [Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.servicelifetime 'Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime') + +The lifetime of the service\. + +#### Returns +[Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') +The same [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') for chaining\. + +#### Exceptions + +[System\.ArgumentNullException](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception 'System\.ArgumentNullException') +[services](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAddWithFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).services 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAddWithFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.services') or [serviceFactory](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAddWithFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).serviceFactory 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAddWithFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.serviceFactory') is [null](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/null 'https://docs\.microsoft\.com/en\-us/dotnet/csharp/language\-reference/keywords/null')\. + +### Remarks +This method only registers the service if no service of type [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAddWithFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAddWithFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService') +has been registered yet\. The factory function is also registered only if not already present\. \ No newline at end of file diff --git a/docs/api/DevElf/ServiceCollectionExtensions.md b/docs/api/DevElf/ServiceCollectionExtensions.md new file mode 100644 index 0000000..90085b8 --- /dev/null +++ b/docs/api/DevElf/ServiceCollectionExtensions.md @@ -0,0 +1,32 @@ +#### [DevElf](README.md 'README') +### [DevElf\.DependencyInjection](DevElf.DependencyInjection.md 'DevElf\.DependencyInjection') + +## ServiceCollectionExtensions Class + +Extension methods for [Microsoft\.Extensions\.DependencyInjection\.IServiceCollection](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection 'Microsoft\.Extensions\.DependencyInjection\.IServiceCollection') that simplify service registration +and factory function patterns in dependency injection\. + +```csharp +public static class ServiceCollectionExtensions +``` + +Inheritance [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') 🡒 ServiceCollectionExtensions + +| Methods | | +| :--- | :--- | +| [Add<TService,TImplementation>\(this IServiceCollection, ServiceLifetime\)](ServiceCollectionExtensions.Add.md#DevElf.DependencyInjection.ServiceCollectionExtensions.Add_TService,TImplementation_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.Add\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Registers a service of type [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.Add_TService,TImplementation_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.Add\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService') with an implementation type of [TImplementation](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.Add_TService,TImplementation_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TImplementation 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.Add\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TImplementation') using the specified lifetime\. | +| [Add<TService>\(this IServiceCollection, ServiceLifetime\)](ServiceCollectionExtensions.Add.md#DevElf.DependencyInjection.ServiceCollectionExtensions.Add_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.Add\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Registers a service of type [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.Add_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.Add\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService') with itself as the implementation type using the specified lifetime\. | +| [Add<TService>\(this IServiceCollection, Func<IServiceProvider,TService>, ServiceLifetime\)](ServiceCollectionExtensions.Add.md#DevElf.DependencyInjection.ServiceCollectionExtensions.Add_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.Add\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Registers a service of type [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.Add_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.Add\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService') using a factory function with the specified lifetime\. | +| [AddFactoryFunc<TService>\(this IServiceCollection, ServiceLifetime\)](ServiceCollectionExtensions.AddFactoryFunc.md#DevElf.DependencyInjection.ServiceCollectionExtensions.AddFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.AddFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Registers a factory function \([System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\) with the specified lifetime that resolves instances of [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.AddFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.AddFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService') from the service provider\. | +| [AddFactoryFunc<TService>\(this IServiceCollection, Func<IServiceProvider,TService>, ServiceLifetime\)](ServiceCollectionExtensions.AddFactoryFunc.md#DevElf.DependencyInjection.ServiceCollectionExtensions.AddFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.AddFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Registers a factory function \([System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\) with the specified lifetime that wraps a custom service factory for creating instances of [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.AddFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.AddFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService')\. | +| [AddWithFactoryFunc<TService,TImplementation>\(this IServiceCollection, ServiceLifetime\)](ServiceCollectionExtensions.AddWithFactoryFunc.md#DevElf.DependencyInjection.ServiceCollectionExtensions.AddWithFactoryFunc_TService,TImplementation_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.AddWithFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Registers a service with its implementation type using the specified lifetime and also registers a factory function \([System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\) that can be injected to create instances on demand\. | +| [AddWithFactoryFunc<TService>\(this IServiceCollection, ServiceLifetime\)](ServiceCollectionExtensions.AddWithFactoryFunc.md#DevElf.DependencyInjection.ServiceCollectionExtensions.AddWithFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.AddWithFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Registers a service with the specified lifetime and also registers a factory function \([System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\) that can be injected to create instances on demand\. | +| [AddWithFactoryFunc<TService>\(this IServiceCollection, Func<IServiceProvider,TService>, ServiceLifetime\)](ServiceCollectionExtensions.AddWithFactoryFunc.md#DevElf.DependencyInjection.ServiceCollectionExtensions.AddWithFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.AddWithFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Registers a service using a factory function with the specified lifetime and also registers a factory function \([System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\) that can be injected to create instances on demand\. | +| [TryAdd<TService,TImplementation>\(this IServiceCollection, ServiceLifetime\)](ServiceCollectionExtensions.TryAdd.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAdd_TService,TImplementation_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAdd\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Tries to register a service of type [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAdd_TService,TImplementation_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAdd\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService') with an implementation type of [TImplementation](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAdd_TService,TImplementation_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TImplementation 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAdd\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TImplementation') using the specified lifetime, if not already registered\. | +| [TryAdd<TService>\(this IServiceCollection, ServiceLifetime\)](ServiceCollectionExtensions.TryAdd.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAdd_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAdd\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Tries to register a service of type [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAdd_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAdd\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService') with itself as the implementation type using the specified lifetime, if not already registered\. | +| [TryAdd<TService>\(this IServiceCollection, Func<IServiceProvider,TService>, ServiceLifetime\)](ServiceCollectionExtensions.TryAdd.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAdd_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAdd\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Tries to register a service of type [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAdd_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAdd\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService') using a factory function with the specified lifetime, if not already registered\. | +| [TryAddFactoryFunc<TService>\(this IServiceCollection, ServiceLifetime\)](ServiceCollectionExtensions.TryAddFactoryFunc.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAddFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAddFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Tries to register a factory function \([System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\) with the specified lifetime \(if not already registered\) that resolves instances of [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAddFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAddFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService') from the service provider\. | +| [TryAddFactoryFunc<TService>\(this IServiceCollection, Func<IServiceProvider,TService>, ServiceLifetime\)](ServiceCollectionExtensions.TryAddFactoryFunc.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAddFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAddFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Tries to register a factory function \([System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\) with the specified lifetime \(if not already registered\) that wraps a custom service factory for creating instances of [TService](ServiceCollectionExtensions.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAddFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime).TService 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAddFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)\.TService')\. | +| [TryAddWithFactoryFunc<TService,TImplementation>\(this IServiceCollection, ServiceLifetime\)](ServiceCollectionExtensions.TryAddWithFactoryFunc.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAddWithFactoryFunc_TService,TImplementation_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAddWithFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Tries to register a service with its implementation type using the specified lifetime \(if not already registered\) and also registers a factory function \([System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\) that can be injected to create instances on demand\. | +| [TryAddWithFactoryFunc<TService>\(this IServiceCollection, ServiceLifetime\)](ServiceCollectionExtensions.TryAddWithFactoryFunc.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAddWithFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAddWithFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Tries to register a service with the specified lifetime \(if not already registered\) and also registers a factory function \([System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\) that can be injected to create instances on demand\. | +| [TryAddWithFactoryFunc<TService>\(this IServiceCollection, Func<IServiceProvider,TService>, ServiceLifetime\)](ServiceCollectionExtensions.TryAddWithFactoryFunc.md#DevElf.DependencyInjection.ServiceCollectionExtensions.TryAddWithFactoryFunc_TService_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,System.Func_System.IServiceProvider,TService_,Microsoft.Extensions.DependencyInjection.ServiceLifetime) 'DevElf\.DependencyInjection\.ServiceCollectionExtensions\.TryAddWithFactoryFunc\\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, System\.Func\, Microsoft\.Extensions\.DependencyInjection\.ServiceLifetime\)') | Tries to register a service using a factory function with the specified lifetime \(if not already registered\) and also registers a factory function \([System\.Func<>](https://learn.microsoft.com/en-us/dotnet/api/system.func-1 'System\.Func\`1')\) that can be injected to create instances on demand\. | diff --git a/src/DevElf/DependencyInjection/ServiceCollectionExtensions.cs b/src/DevElf/DependencyInjection/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..f45b978 --- /dev/null +++ b/src/DevElf/DependencyInjection/ServiceCollectionExtensions.cs @@ -0,0 +1,514 @@ +using DevElf.ArgumentValidation; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; + +namespace DevElf.DependencyInjection; + +/// +/// Extension methods for that simplify service registration +/// and factory function patterns in dependency injection. +/// +public static class ServiceCollectionExtensions +{ + /// + /// Registers a service with the specified lifetime and also registers a factory function + /// () that can be injected to create instances on demand. + /// + /// The type of service to register. Must be a class. + /// The to add the services to. + /// The lifetime of the service. + /// The same for chaining. + /// is . + /// + /// + /// services.AddWithFactoryFunc<IMyService>(ServiceLifetime.Scoped); + /// + /// // Later, inject Func<IMyService> to create instances on demand: + /// public class Consumer(Func<IMyService> serviceFactory) + /// { + /// public void DoWork() + /// { + /// var service = serviceFactory(); + /// // use service... + /// } + /// } + /// + /// + public static IServiceCollection AddWithFactoryFunc( + this IServiceCollection services, + ServiceLifetime serviceLifetime) + where TService : class + { + services.ThrowIfNull(); + + return services + .Add(serviceLifetime) + .AddFactoryFunc(ServiceLifetime.Singleton); + } + + /// + /// Registers a service using a factory function with the specified lifetime and also registers + /// a factory function () that can be injected to create instances on demand. + /// + /// The type of service to register. Must be a class. + /// The to add the services to. + /// The factory function that creates instances of the service. + /// The lifetime of the service. + /// The same for chaining. + /// + /// or is . + /// + /// + /// + /// services.AddWithFactoryFunc<IMyService>( + /// sp => new MyService(sp.GetRequiredService<IDependency>()), + /// ServiceLifetime.Transient); + /// + /// + public static IServiceCollection AddWithFactoryFunc( + this IServiceCollection services, + Func serviceFactory, + ServiceLifetime serviceLifetime) + where TService : class + { + services.ThrowIfNull(); + serviceFactory.ThrowIfNull(); + + return services + .Add(serviceFactory, serviceLifetime) + .AddFactoryFunc(ServiceLifetime.Singleton); + } + + /// + /// Registers a service with its implementation type using the specified lifetime and also registers + /// a factory function () that can be injected to create instances on demand. + /// + /// The service type to register. Must be a class. + /// + /// The implementation type that implements . + /// + /// The to add the services to. + /// The lifetime of the service. + /// The same for chaining. + /// is . + /// + /// + /// services.AddWithFactoryFunc<IMyService, MyServiceImpl>(ServiceLifetime.Singleton); + /// + /// + public static IServiceCollection AddWithFactoryFunc( + this IServiceCollection services, + ServiceLifetime serviceLifetime) + where TService : class + where TImplementation : TService + { + services.ThrowIfNull(); + + return services + .Add(serviceLifetime) + .AddFactoryFunc(ServiceLifetime.Singleton); + } + + /// + /// Tries to register a service with the specified lifetime (if not already registered) and also + /// registers a factory function () that can be injected to create + /// instances on demand. + /// + /// The type of service to register. Must be a class. + /// The to add the services to. + /// The lifetime of the service. + /// The same for chaining. + /// is . + /// + /// This method only registers the service if no service of type + /// has been registered yet. The factory function is also registered only if not already present. + /// + public static IServiceCollection TryAddWithFactoryFunc( + this IServiceCollection services, + ServiceLifetime serviceLifetime) + where TService : class + { + services.ThrowIfNull(); + + return services + .TryAdd(serviceLifetime) + .TryAddFactoryFunc(ServiceLifetime.Singleton); + } + + /// + /// Tries to register a service using a factory function with the specified lifetime + /// (if not already registered) and also registers a factory function () + /// that can be injected to create instances on demand. + /// + /// The type of service to register. Must be a class. + /// The to add the services to. + /// The factory function that creates instances of the service. + /// The lifetime of the service. + /// The same for chaining. + /// + /// or is . + /// + /// + /// This method only registers the service if no service of type + /// has been registered yet. The factory function is also registered only if not already present. + /// + public static IServiceCollection TryAddWithFactoryFunc( + this IServiceCollection services, + Func serviceFactory, + ServiceLifetime serviceLifetime) + where TService : class + { + services.ThrowIfNull(); + serviceFactory.ThrowIfNull(); + + return services + .TryAdd(serviceFactory, serviceLifetime) + .TryAddFactoryFunc(ServiceLifetime.Singleton); + } + + /// + /// Tries to register a service with its implementation type using the specified lifetime + /// (if not already registered) and also registers a factory function () + /// that can be injected to create instances on demand. + /// + /// The service type to register. Must be a class. + /// + /// The implementation type that implements . + /// + /// The to add the services to. + /// The lifetime of the service. + /// The same for chaining. + /// is . + /// + /// This method only registers the service if no service of type + /// has been registered yet. The factory function is also registered only if not already present. + /// + public static IServiceCollection TryAddWithFactoryFunc( + this IServiceCollection services, + ServiceLifetime serviceLifetime) + where TService : class + where TImplementation : TService + { + services.ThrowIfNull(); + + return services + .TryAdd(serviceLifetime) + .TryAddFactoryFunc(ServiceLifetime.Singleton); + } + + /// + /// Registers a factory function () with the specified lifetime + /// that resolves instances of from the service provider. + /// + /// The type of service the factory will create. Must be a class. + /// The to add the factory to. + /// The lifetime of the factory function itself. + /// The same for chaining. + /// is . + /// + /// The factory function calls + /// to resolve the service when invoked. The service itself must be registered separately. + /// + /// + /// + /// services.AddScoped<IMyService, MyServiceImpl>(); + /// services.AddFactoryFunc<IMyService>(ServiceLifetime.Singleton); + /// + /// // Later, inject Func<IMyService> to create instances on demand + /// + /// + public static IServiceCollection AddFactoryFunc( + this IServiceCollection services, + ServiceLifetime factoryLifetime) + where TService : class + { + services.ThrowIfNull(); + + return services.Add>( + serviceProvider => serviceProvider.GetRequiredService, + factoryLifetime); + } + + /// + /// Registers a factory function () with the specified lifetime + /// that wraps a custom service factory for creating instances of . + /// + /// The type of service the factory will create. Must be a class. + /// The to add the factory to. + /// The factory function that creates instances of the service. + /// The lifetime of the factory function itself. + /// The same for chaining. + /// + /// or is . + /// + /// + /// This overload wraps the provided in a parameter-less function + /// that can be injected as . + /// + /// + /// + /// services.AddFactoryFunc<IMyService>( + /// sp => new MyService(sp.GetRequiredService<IDependency>()), + /// ServiceLifetime.Singleton); + /// + /// + public static IServiceCollection AddFactoryFunc( + this IServiceCollection services, + Func serviceFactory, + ServiceLifetime factoryLifetime) + where TService : class + { + services.ThrowIfNull(); + serviceFactory.ThrowIfNull(); + + return services.Add>( + serviceProvider => () => serviceFactory(serviceProvider), + factoryLifetime); + } + + /// + /// Tries to register a factory function () with the specified lifetime + /// (if not already registered) that resolves instances of from the service provider. + /// + /// The type of service the factory will create. Must be a class. + /// The to add the factory to. + /// The lifetime of the factory function itself. + /// The same for chaining. + /// is . + /// + /// This method only registers the factory if no factory of type + /// has been registered yet. + /// + public static IServiceCollection TryAddFactoryFunc( + this IServiceCollection services, + ServiceLifetime factoryLifetime) + where TService : class + { + services.ThrowIfNull(); + + return services.TryAdd>( + serviceProvider => serviceProvider.GetRequiredService, + factoryLifetime); + } + + /// + /// Tries to register a factory function () with the specified lifetime + /// (if not already registered) that wraps a custom service factory for creating instances of . + /// + /// The type of service the factory will create. Must be a class. + /// The to add the factory to. + /// The factory function that creates instances of the service. + /// The lifetime of the factory function itself. + /// The same for chaining. + /// + /// or is . + /// + /// + /// This method only registers the factory if no factory of type + /// has been registered yet. + /// + public static IServiceCollection TryAddFactoryFunc( + this IServiceCollection services, + Func serviceFactory, + ServiceLifetime factoryLifetime) + where TService : class + { + services.ThrowIfNull(); + serviceFactory.ThrowIfNull(); + + return services.TryAdd>( + serviceProvider => () => serviceFactory(serviceProvider), + factoryLifetime); + } + + /// + /// Registers a service of type with itself as the implementation + /// type using the specified lifetime. + /// + /// The type of service to register. Must be a class. + /// The to add the service to. + /// The lifetime of the service. + /// The same for chaining. + /// is . + /// + /// + /// services.Add<MyService>(ServiceLifetime.Transient); + /// + /// + public static IServiceCollection Add( + this IServiceCollection services, + ServiceLifetime lifetime) + where TService : class + { + services.ThrowIfNull(); + + services.Add(new ServiceDescriptor( + typeof(TService), + typeof(TService), + lifetime)); + + return services; + } + + /// + /// Registers a service of type using a factory function + /// with the specified lifetime. + /// + /// The type of service to register. Must be a class. + /// The to add the service to. + /// The factory function that creates instances of the service. + /// The lifetime of the service. + /// The same for chaining. + /// + /// or is . + /// + /// + /// + /// services.Add<IMyService>( + /// sp => new MyService(sp.GetRequiredService<IDependency>()), + /// ServiceLifetime.Scoped); + /// + /// + public static IServiceCollection Add( + this IServiceCollection services, + Func serviceFactory, + ServiceLifetime lifetime) + where TService : class + { + services.ThrowIfNull(); + serviceFactory.ThrowIfNull(); + + services.Add(new ServiceDescriptor( + typeof(TService), + serviceFactory, + lifetime)); + + return services; + } + + /// + /// Registers a service of type with an implementation type + /// of using the specified lifetime. + /// + /// The service type to register. Must be a class. + /// + /// The implementation type that implements . + /// + /// The to add the service to. + /// The lifetime of the service. + /// The same for chaining. + /// is . + /// + /// + /// services.Add<IMyService, MyServiceImpl>(ServiceLifetime.Singleton); + /// + /// + public static IServiceCollection Add( + this IServiceCollection services, + ServiceLifetime lifetime) + where TService : class + where TImplementation : TService + { + services.ThrowIfNull(); + + services.Add(new ServiceDescriptor( + typeof(TService), + typeof(TImplementation), + lifetime)); + + return services; + } + + /// + /// Tries to register a service of type with itself as the implementation + /// type using the specified lifetime, if not already registered. + /// + /// The type of service to register. Must be a class. + /// The to add the service to. + /// The lifetime of the service. + /// The same for chaining. + /// is . + /// + /// This method only registers the service if no service of type + /// has been registered yet. + /// + public static IServiceCollection TryAdd( + this IServiceCollection services, + ServiceLifetime lifetime) + where TService : class + { + services.ThrowIfNull(); + + services.TryAdd(new ServiceDescriptor( + typeof(TService), + typeof(TService), + lifetime)); + + return services; + } + + /// + /// Tries to register a service of type using a factory function + /// with the specified lifetime, if not already registered. + /// + /// The type of service to register. Must be a class. + /// The to add the service to. + /// The factory function that creates instances of the service. + /// The lifetime of the service. + /// The same for chaining. + /// + /// or is . + /// + /// + /// This method only registers the service if no service of type + /// has been registered yet. + /// + public static IServiceCollection TryAdd( + this IServiceCollection services, + Func serviceFactory, + ServiceLifetime lifetime) + where TService : class + { + services.ThrowIfNull(); + serviceFactory.ThrowIfNull(); + + services.TryAdd(new ServiceDescriptor( + typeof(TService), + serviceFactory, + lifetime)); + + return services; + } + + /// + /// Tries to register a service of type with an implementation type + /// of using the specified lifetime, if not already registered. + /// + /// The service type to register. Must be a class. + /// + /// The implementation type that implements . + /// + /// The to add the service to. + /// The lifetime of the service. + /// The same for chaining. + /// is . + /// + /// This method only registers the service if no service of type + /// has been registered yet. + /// + public static IServiceCollection TryAdd( + this IServiceCollection services, + ServiceLifetime lifetime) + where TService : class + where TImplementation : TService + { + services.ThrowIfNull(); + + services.TryAdd(new ServiceDescriptor( + typeof(TService), + typeof(TImplementation), + lifetime)); + + return services; + } +} diff --git a/src/DevElf/DevElf.csproj b/src/DevElf/DevElf.csproj index 988ed46..f1998fc 100644 --- a/src/DevElf/DevElf.csproj +++ b/src/DevElf/DevElf.csproj @@ -9,5 +9,10 @@ + + + + + diff --git a/src/DevElf/Logging/LoggerExtensions.cs b/src/DevElf/Logging/LoggerExtensions.cs new file mode 100644 index 0000000..aa2c966 --- /dev/null +++ b/src/DevElf/Logging/LoggerExtensions.cs @@ -0,0 +1,52 @@ +using DevElf.ArgumentValidation; +using Microsoft.Extensions.Logging; + +namespace DevElf.Logging; + +/// +/// Provides extension methods for to enhance logging capabilities. +/// +public static class LoggerExtensions +{ + /// + /// Creates a new logging scope properties builder with the specified property. + /// + /// The logger instance to create a scope for. + /// The name of the property to add to the logging scope. + /// The value of the property to add to the logging scope. + /// + /// A that can be used to add more properties + /// or begin the logging scope. + /// + /// + /// Thrown when or is . + /// + /// + /// Thrown when is empty or contains only whitespace. + /// + /// + /// This method provides a fluent API for building logging scopes with multiple properties. + /// Use the returned builder to add additional properties via + /// and then call to create the scope. + /// + /// + /// + /// using (logger.AddProperty("UserId", userId) + /// .AddProperty("RequestId", requestId) + /// .BeginScope()) + /// { + /// logger.LogInformation("Processing request"); + /// } + /// + /// + public static LoggingScopePropertiesBuilder AddProperty( + this ILogger logger, + string name, + object? value) + { + logger.ThrowIfNull(); + name.ThrowIfNullOrWhiteSpace(); + + return new(logger, name, value); + } +} diff --git a/src/DevElf/Logging/LoggingScopePropertiesBuilder.cs b/src/DevElf/Logging/LoggingScopePropertiesBuilder.cs new file mode 100644 index 0000000..7a6fff8 --- /dev/null +++ b/src/DevElf/Logging/LoggingScopePropertiesBuilder.cs @@ -0,0 +1,87 @@ +using DevElf.ArgumentValidation; +using Microsoft.Extensions.Logging; + +namespace DevElf.Logging; + +/// +/// Provides a fluent API for building logging scopes with multiple properties. +/// +/// +/// This class is typically created using the extension method +/// and allows chaining multiple property additions before beginning the scope. +/// +public sealed class LoggingScopePropertiesBuilder +{ + private readonly ILogger logger; + private readonly Dictionary properties = []; + + /// + /// Initializes a new instance of the class. + /// + /// The logger instance to create a scope for. + /// The name of the first property to add. + /// The value of the first property to add. + /// + /// Thrown when or is . + /// + /// + /// Thrown when is empty or contains only whitespace. + /// + internal LoggingScopePropertiesBuilder(ILogger logger, string name, object? value) + { + name.ThrowIfNullOrWhiteSpace(); + + this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); + this.properties.Add(name, value); + } + + /// + /// Adds or updates a property in the logging scope. + /// + /// The name of the property to add or update. + /// The value of the property. + /// + /// The current instance for method chaining. + /// + /// + /// Thrown when is . + /// + /// + /// Thrown when is empty or contains only whitespace. + /// + /// + /// If a property with the same name already exists, its value will be replaced with the new value. + /// + public LoggingScopePropertiesBuilder AddProperty(string name, object? value) + { + name.ThrowIfNullOrWhiteSpace(); + + this.properties[name] = value; + + return this; + } + + /// + /// Begins a new logging scope with all the properties that have been added. + /// + /// + /// An that ends the scope when disposed, or + /// if the logger does not support scopes. + /// + /// + /// The returned should be disposed to properly end the logging scope. + /// It's recommended to use this within a statement to ensure proper cleanup. + /// + /// + /// + /// using (logger.AddProperty("UserId", userId) + /// .AddProperty("OperationId", operationId) + /// .BeginScope()) + /// { + /// logger.LogInformation("Operation started"); + /// // All logs within this scope will include UserId and OperationId + /// } + /// + /// + public IDisposable? BeginScope() => this.logger.BeginScope(this.properties); +} diff --git a/src/DevElf/Threading/RateLimiting/NoLimitRateLimiter.cs b/src/DevElf/Threading/RateLimiting/NoLimitRateLimiter.cs new file mode 100644 index 0000000..4a9ad4a --- /dev/null +++ b/src/DevElf/Threading/RateLimiting/NoLimitRateLimiter.cs @@ -0,0 +1,122 @@ +using System.Threading.RateLimiting; + +namespace DevElf.Threading.RateLimiting; + +/// +/// A implementation that imposes no limits on permit acquisition. +/// All requests for permits are immediately granted without any restrictions. +/// +/// +/// +/// This rate limiter is useful in scenarios where rate limiting needs to be conditionally +/// disabled or for testing purposes. It always returns acquired leases immediately, +/// regardless of the number of permits requested. +/// +/// +/// Use the singleton to avoid unnecessary allocations. +/// +/// +/// +/// +/// // Use the singleton instance +/// RateLimiter limiter = NoLimitRateLimiter.Instance; +/// +/// // All acquisitions succeed immediately +/// using var lease = await limiter.AcquireAsync(permitCount: 100); +/// // lease.IsAcquired will always be true +/// +/// +public class NoLimitRateLimiter : RateLimiter +{ + /// + /// Gets the singleton instance of . + /// + /// + /// Using this instance avoids creating multiple instances of the same + /// no-op rate limiter. + /// + public static readonly NoLimitRateLimiter Instance = new(); + + /// + /// Gets the idle duration, which is always for this limiter + /// since there is never any waiting required. + /// + public override TimeSpan? IdleDuration { get; } + + /// + /// Gets the rate limiter statistics. Always returns since + /// this limiter does not track any statistics. + /// + /// Always . + public override RateLimiterStatistics? GetStatistics() => null; + + /// + /// Asynchronously acquires permits. Always succeeds immediately regardless of + /// the permit count. + /// + /// + /// The number of permits to acquire. This parameter is ignored since all + /// acquisitions succeed. + /// + /// + /// A token to monitor for cancellation requests. This parameter is ignored since + /// the operation completes synchronously. + /// + /// + /// A that completes immediately with an acquired lease. + /// + protected override ValueTask AcquireAsyncCore(int permitCount, CancellationToken cancellationToken) + => ValueTask.FromResult(NoLimitLease.LeaseInstance); + + /// + /// Attempts to acquire permits synchronously. Always succeeds immediately + /// regardless of the permit count. + /// + /// + /// The number of permits to acquire. This parameter is ignored since all + /// acquisitions succeed. + /// + /// An acquired . + protected override RateLimitLease AttemptAcquireCore(int permitCount) => NoLimitLease.LeaseInstance; + + /// + /// Represents a lease from that is always acquired + /// and contains no metadata. + /// + protected sealed class NoLimitLease : RateLimitLease + { + /// + /// Gets the singleton instance of . + /// + public static readonly RateLimitLease LeaseInstance = new NoLimitLease(); + + /// + /// Gets a value indicating whether the lease was acquired. Always returns + /// . + /// + public override bool IsAcquired => true; + + /// + /// Gets the metadata names associated with this lease. Always returns an + /// empty collection since this lease contains no metadata. + /// + public override IEnumerable MetadataNames { get; } = []; + + /// + /// Attempts to retrieve metadata by name. Always returns + /// since this lease contains no metadata. + /// + /// The name of the metadata to retrieve. + /// + /// When this method returns, contains . + /// + /// Always . + public override bool TryGetMetadata(string metadataName, out object? metadata) + { + metadata = default; + + return false; + } + } +} + diff --git a/src/DevElf/Threading/RateLimiting/RateLimiterExtensions.cs b/src/DevElf/Threading/RateLimiting/RateLimiterExtensions.cs new file mode 100644 index 0000000..a0f9c1c --- /dev/null +++ b/src/DevElf/Threading/RateLimiting/RateLimiterExtensions.cs @@ -0,0 +1,221 @@ +using System.Threading.RateLimiting; +using DevElf.ArgumentValidation; + +namespace DevElf.Threading.RateLimiting; + +/// +/// Provides extension methods for to simplify applying +/// rate limiting to actions and requests. +/// +public static class RateLimiterExtensions +{ + private const int DefaultIdleTimeMicroseconds = 100; + + /// + /// Applies rate limiting to an asynchronous action, automatically acquiring and + /// releasing permits. + /// + /// The rate limiter to be used. + /// The action to execute once permits are acquired. + /// + /// The number of permits needed to execute the action. Must be positive. + /// Defaults to 1. + /// + /// + /// The time to wait between permit acquisition attempts when permits are not + /// immediately available. When , defaults to 100 + /// microseconds. This prevents busy-waiting while allowing responsive permit + /// acquisition. + /// + /// + /// The to use for time-based operations during idle + /// waits. When , defaults to . + /// + /// + /// A token to monitor for cancellation requests during permit acquisition and + /// action execution. + /// + /// A task that completes when the action has been executed. + /// + /// If or is + /// . + /// + /// + /// If the is canceled before or during + /// execution. + /// + /// + /// + /// This method repeatedly attempts to acquire the specified number of permits. + /// If permits are not immediately available, it waits for the specified + /// before trying again. Once permits are acquired, + /// the action is executed and the permits are automatically released. + /// + /// + /// The lease is properly disposed even if the action throws an exception, + /// ensuring permits are returned to the limiter. + /// + /// + /// + /// + /// var limiter = new TokenBucketRateLimiter(new TokenBucketRateLimiterOptions + /// { + /// TokenLimit = 10, + /// ReplenishmentPeriod = TimeSpan.FromSeconds(1), + /// TokensPerPeriod = 10 + /// }); + /// + /// await limiter.ApplyToAsync( + /// async ct => await SendEmailAsync(ct), + /// permitCount: 1, + /// cancellationToken: cancellationToken); + /// + /// + public static async Task ApplyToAsync( + this RateLimiter limiter, + Func action, + int permitCount = 1, + TimeSpan? idleTime = null, + TimeProvider? timeProvider = null, + CancellationToken cancellationToken = default) + { + limiter.ThrowIfNull(); + action.ThrowIfNull(); + + timeProvider ??= TimeProvider.System; + RateLimitLease lease; + + do + { + lease = await limiter.AcquireAsync(permitCount, cancellationToken).ConfigureAwait(false); + + if (!lease.IsAcquired) + { + lease.Dispose(); + await Task + .Delay( + idleTime ?? TimeSpan.FromMicroseconds(DefaultIdleTimeMicroseconds), + timeProvider, + cancellationToken) + .ConfigureAwait(false); + } + } + while (!lease.IsAcquired); + + try + { + await action(cancellationToken).ConfigureAwait(false); + } + finally + { + lease.Dispose(); + } + } + + /// + /// Applies rate limiting to an asynchronous request, automatically acquiring and + /// releasing permits, and returns the result. + /// + /// The type of the result returned by the request. + /// The rate limiter to be used. + /// + /// The request function to execute once permits are acquired. + /// + /// + /// The number of permits needed to execute the request. Must be positive. + /// Defaults to 1. + /// + /// + /// The time to wait between permit acquisition attempts when permits are not + /// immediately available. When , defaults to 100 + /// microseconds. This prevents busy-waiting while allowing responsive permit + /// acquisition. + /// + /// + /// The to use for time-based operations during idle + /// waits. When , defaults to . + /// + /// + /// A token to monitor for cancellation requests during permit acquisition and + /// request execution. + /// + /// + /// A task that represents the asynchronous operation. The task result contains + /// the value returned by the request function. + /// + /// + /// If or is + /// . + /// + /// + /// If the is canceled before or during + /// execution. + /// + /// + /// + /// This method repeatedly attempts to acquire the specified number of permits. + /// If permits are not immediately available, it waits for the specified + /// before trying again. Once permits are acquired, + /// the request is executed and the permits are automatically released. + /// + /// + /// The lease is properly disposed even if the request throws an exception, + /// ensuring permits are returned to the limiter. + /// + /// + /// + /// + /// var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions + /// { + /// PermitLimit = 5, + /// QueueLimit = 10 + /// }); + /// + /// var response = await limiter.ApplyToAsync( + /// async ct => await httpClient.GetAsync(url, ct), + /// permitCount: 1, + /// cancellationToken: cancellationToken); + /// + /// + public static async Task ApplyToAsync( + this RateLimiter limiter, + Func> request, + int permitCount = 1, + TimeSpan? idleTime = null, + TimeProvider? timeProvider = null, + CancellationToken cancellationToken = default) + { + limiter.ThrowIfNull(); + request.ThrowIfNull(); + + timeProvider ??= TimeProvider.System; + RateLimitLease lease; + + do + { + lease = await limiter.AcquireAsync(permitCount, cancellationToken).ConfigureAwait(false); + + if (!lease.IsAcquired) + { + lease.Dispose(); + await Task + .Delay( + idleTime ?? TimeSpan.FromMicroseconds(DefaultIdleTimeMicroseconds), + timeProvider, + cancellationToken) + .ConfigureAwait(false); + } + } + while (!lease.IsAcquired); + + try + { + return await request(cancellationToken).ConfigureAwait(false); + } + finally + { + lease.Dispose(); + } + } +} + diff --git a/tests/DevElf.Logging.Tests/LoggerExtensionsTests.cs b/tests/DevElf.Logging.Tests/LoggerExtensionsTests.cs new file mode 100644 index 0000000..3f40b06 --- /dev/null +++ b/tests/DevElf.Logging.Tests/LoggerExtensionsTests.cs @@ -0,0 +1,146 @@ +using AwesomeAssertions; +using Microsoft.Extensions.Logging; +using NSubstitute; + +namespace DevElf.Logging.Tests; + +[TestClass] +public class LoggerExtensionsTests +{ + #region AddProperty Tests + + [TestMethod] + public void AddProperty_creates_builder_with_single_property() + { + // Arrange + ILogger logger = Substitute.For(); + string propertyName = "TestProperty"; + object propertyValue = "TestValue"; + + // Act + LoggingScopePropertiesBuilder builder = logger.AddProperty(propertyName, propertyValue); + + // Assert + _ = builder.Should().NotBeNull(); + } + + [TestMethod] + public void AddProperty_throws_ArgumentNullException_when_logger_is_null() + { + // Arrange + ILogger? logger = null; + string propertyName = "TestProperty"; + object propertyValue = "TestValue"; + + // Act + Action act = () => logger!.AddProperty(propertyName, propertyValue); + + // Assert + _ = act.Should().Throw() + .WithParameterName("logger"); + } + + [TestMethod] + public void AddProperty_throws_ArgumentNullException_when_name_is_null() + { + // Arrange + ILogger logger = Substitute.For(); + string? propertyName = null; + object propertyValue = "TestValue"; + + // Act + Action act = () => logger.AddProperty(propertyName!, propertyValue); + + // Assert + _ = act.Should().Throw() + .WithParameterName("name"); + } + + [TestMethod] + public void AddProperty_throws_ArgumentException_when_name_is_empty() + { + // Arrange + ILogger logger = Substitute.For(); + string propertyName = string.Empty; + object propertyValue = "TestValue"; + + // Act + Action act = () => logger.AddProperty(propertyName, propertyValue); + + // Assert + _ = act.Should().Throw() + .WithParameterName("name"); + } + + [TestMethod] + public void AddProperty_throws_ArgumentException_when_name_is_whitespace() + { + // Arrange + ILogger logger = Substitute.For(); + string propertyName = " "; + object propertyValue = "TestValue"; + + // Act + Action act = () => logger.AddProperty(propertyName, propertyValue); + + // Assert + _ = act.Should().Throw() + .WithParameterName("name"); + } + + [TestMethod] + public void AddProperty_accepts_null_value() + { + // Arrange + ILogger logger = Substitute.For(); + string propertyName = "TestProperty"; + object? propertyValue = null; + + // Act + LoggingScopePropertiesBuilder builder = logger.AddProperty(propertyName, propertyValue); + + // Assert + _ = builder.Should().NotBeNull(); + } + + [TestMethod] + public void AddProperty_allows_fluent_chaining() + { + // Arrange + ILogger logger = Substitute.For(); + Dictionary capturedProperties = null!; + _ = logger.BeginScope(Arg.Do>(props => capturedProperties = props)); + + // Act + _ = logger.AddProperty("Property1", "Value1") + .AddProperty("Property2", 42) + .AddProperty("Property3", true) + .BeginScope(); + + // Assert + _ = capturedProperties.Should().NotBeNull(); + _ = capturedProperties.Should().HaveCount(3); + _ = capturedProperties["Property1"].Should().Be("Value1"); + _ = capturedProperties["Property2"].Should().Be(42); + _ = capturedProperties["Property3"].Should().Be(true); + } + + [TestMethod] + public void AddProperty_with_complex_object_value() + { + // Arrange + ILogger logger = Substitute.For(); + Dictionary capturedProperties = null!; + _ = logger.BeginScope(Arg.Do>(props => capturedProperties = props)); + var complexValue = new { Id = 123, Name = "Test" }; + + // Act + _ = logger.AddProperty("ComplexProperty", complexValue).BeginScope(); + + // Assert + _ = capturedProperties.Should().NotBeNull(); + _ = capturedProperties["ComplexProperty"].Should().BeSameAs(complexValue); + } + + #endregion +} diff --git a/tests/DevElf.Logging.Tests/LoggingScopePropertiesBuilderTests.cs b/tests/DevElf.Logging.Tests/LoggingScopePropertiesBuilderTests.cs new file mode 100644 index 0000000..5b7277e --- /dev/null +++ b/tests/DevElf.Logging.Tests/LoggingScopePropertiesBuilderTests.cs @@ -0,0 +1,271 @@ +using AwesomeAssertions; +using Microsoft.Extensions.Logging; +using NSubstitute; + +namespace DevElf.Logging.Tests; + +[TestClass] +public class LoggingScopePropertiesBuilderTests +{ + #region AddProperty Tests + + [TestMethod] + public void AddProperty_adds_multiple_properties() + { + // Arrange + ILogger logger = Substitute.For(); + Dictionary capturedProperties = null!; + _ = logger.BeginScope(Arg.Do>(props => capturedProperties = props)); + LoggingScopePropertiesBuilder builder = logger.AddProperty("Property1", "Value1"); + + // Act + _ = builder.AddProperty("Property2", 42) + .AddProperty("Property3", true) + .BeginScope(); + + // Assert + _ = capturedProperties.Should().HaveCount(3); + _ = capturedProperties["Property1"].Should().Be("Value1"); + _ = capturedProperties["Property2"].Should().Be(42); + _ = capturedProperties["Property3"].Should().Be(true); + } + + [TestMethod] + public void AddProperty_returns_same_builder_instance() + { + // Arrange + ILogger logger = Substitute.For(); + LoggingScopePropertiesBuilder builder = logger.AddProperty("Property1", "Value1"); + + // Act + LoggingScopePropertiesBuilder result = builder.AddProperty("Property2", "Value2"); + + // Assert + _ = result.Should().BeSameAs(builder); + } + + [TestMethod] + public void AddProperty_overwrites_existing_property_with_same_name() + { + // Arrange + ILogger logger = Substitute.For(); + Dictionary capturedProperties = null!; + _ = logger.BeginScope(Arg.Do>(props => capturedProperties = props)); + LoggingScopePropertiesBuilder builder = logger.AddProperty("Property1", "OriginalValue"); + + // Act + _ = builder.AddProperty("Property1", "UpdatedValue").BeginScope(); + + // Assert + _ = capturedProperties.Should().HaveCount(1); + _ = capturedProperties["Property1"].Should().Be("UpdatedValue"); + } + + [TestMethod] + public void AddProperty_accepts_null_values() + { + // Arrange + ILogger logger = Substitute.For(); + Dictionary capturedProperties = null!; + _ = logger.BeginScope(Arg.Do>(props => capturedProperties = props)); + LoggingScopePropertiesBuilder builder = logger.AddProperty("Property1", "Value1"); + + // Act + _ = builder.AddProperty("Property2", null).BeginScope(); + + // Assert + _ = capturedProperties.Should().HaveCount(2); + _ = capturedProperties["Property2"].Should().BeNull(); + } + + [TestMethod] + public void AddProperty_throws_ArgumentNullException_when_name_is_null() + { + // Arrange + ILogger logger = Substitute.For(); + LoggingScopePropertiesBuilder builder = logger.AddProperty("Property1", "Value1"); + + // Act + Action act = () => builder.AddProperty(null!, "Value"); + + // Assert + _ = act.Should().Throw() + .WithParameterName("name"); + } + + [TestMethod] + public void AddProperty_throws_ArgumentException_when_name_is_empty() + { + // Arrange + ILogger logger = Substitute.For(); + LoggingScopePropertiesBuilder builder = logger.AddProperty("Property1", "Value1"); + + // Act + Action act = () => builder.AddProperty(string.Empty, "Value"); + + // Assert + _ = act.Should().Throw() + .WithParameterName("name"); + } + + [TestMethod] + public void AddProperty_throws_ArgumentException_when_name_is_whitespace() + { + // Arrange + ILogger logger = Substitute.For(); + LoggingScopePropertiesBuilder builder = logger.AddProperty("Property1", "Value1"); + + // Act + Action act = () => builder.AddProperty(" ", "Value"); + + // Assert + _ = act.Should().Throw() + .WithParameterName("name"); + } + + #endregion + + #region BeginScope Tests + + [TestMethod] + public void BeginScope_calls_logger_with_all_properties() + { + // Arrange + ILogger logger = Substitute.For(); + Dictionary capturedProperties = null!; + _ = logger.BeginScope(Arg.Do>(props => capturedProperties = props)); + LoggingScopePropertiesBuilder builder = logger.AddProperty("Property1", "Value1") + .AddProperty("Property2", 42); + + // Act + _ = builder.BeginScope(); + + // Assert + _ = logger.Received(1).BeginScope(Arg.Any>()); + _ = capturedProperties.Should().NotBeNull(); + _ = capturedProperties.Should().HaveCount(2); + } + + [TestMethod] + public void BeginScope_returns_disposable_from_logger() + { + // Arrange + ILogger logger = Substitute.For(); + IDisposable expectedDisposable = Substitute.For(); + _ = logger.BeginScope(Arg.Any>()).Returns(expectedDisposable); + LoggingScopePropertiesBuilder builder = logger.AddProperty("Property1", "Value1"); + + // Act + IDisposable? result = builder.BeginScope(); + + // Assert + _ = result.Should().BeSameAs(expectedDisposable); + } + + [TestMethod] + public void BeginScope_returns_null_when_logger_returns_null() + { + // Arrange + ILogger logger = Substitute.For(); + _ = logger.BeginScope(Arg.Any>()).Returns((IDisposable?)null); + LoggingScopePropertiesBuilder builder = logger.AddProperty("Property1", "Value1"); + + // Act + IDisposable? result = builder.BeginScope(); + + // Assert + _ = result.Should().BeNull(); + } + + [TestMethod] + public void BeginScope_can_be_called_multiple_times() + { + // Arrange + ILogger logger = Substitute.For(); + LoggingScopePropertiesBuilder builder = logger.AddProperty("Property1", "Value1"); + + // Act + _ = builder.BeginScope(); + _ = builder.BeginScope(); + + // Assert + _ = logger.Received(2).BeginScope(Arg.Any>()); + } + + #endregion + + #region Constructor and Initial Property Tests + + [TestMethod] + public void builder_includes_initial_property_from_constructor() + { + // Arrange + ILogger logger = Substitute.For(); + Dictionary capturedProperties = null!; + _ = logger.BeginScope(Arg.Do>(props => capturedProperties = props)); + + // Act + _ = logger.AddProperty("InitialProperty", "InitialValue").BeginScope(); + + // Assert + _ = capturedProperties.Should().HaveCount(1); + _ = capturedProperties["InitialProperty"].Should().Be("InitialValue"); + } + + #endregion + + #region Property Order and Type Tests + + [TestMethod] + public void builder_preserves_property_order() + { + // Arrange + ILogger logger = Substitute.For(); + Dictionary capturedProperties = null!; + _ = logger.BeginScope(Arg.Do>(props => capturedProperties = props)); + + // Act + _ = logger.AddProperty("First", 1) + .AddProperty("Second", 2) + .AddProperty("Third", 3) + .BeginScope(); + + // Assert + string[] keys = capturedProperties.Keys.ToArray(); + _ = keys[0].Should().Be("First"); + _ = keys[1].Should().Be("Second"); + _ = keys[2].Should().Be("Third"); + } + + [TestMethod] + public void builder_works_with_various_value_types() + { + // Arrange + ILogger logger = Substitute.For(); + Dictionary capturedProperties = null!; + _ = logger.BeginScope(Arg.Do>(props => capturedProperties = props)); + DateTime dateTime = DateTime.UtcNow; + Guid guid = Guid.NewGuid(); + + // Act + _ = logger.AddProperty("String", "test") + .AddProperty("Int", 42) + .AddProperty("Double", 3.14) + .AddProperty("Bool", true) + .AddProperty("DateTime", dateTime) + .AddProperty("Guid", guid) + .AddProperty("Null", null) + .BeginScope(); + + // Assert + _ = capturedProperties["String"].Should().Be("test"); + _ = capturedProperties["Int"].Should().Be(42); + _ = capturedProperties["Double"].Should().Be(3.14); + _ = capturedProperties["Bool"].Should().Be(true); + _ = capturedProperties["DateTime"].Should().Be(dateTime); + _ = capturedProperties["Guid"].Should().Be(guid); + _ = capturedProperties["Null"].Should().BeNull(); + } + + #endregion +} diff --git a/tests/DevElf.Tests/DependencyInjection/ServiceCollectionExtensionsTests.cs b/tests/DevElf.Tests/DependencyInjection/ServiceCollectionExtensionsTests.cs new file mode 100644 index 0000000..75fab7f --- /dev/null +++ b/tests/DevElf.Tests/DependencyInjection/ServiceCollectionExtensionsTests.cs @@ -0,0 +1,1155 @@ +using AutoFixture; +using AwesomeAssertions; +using DevElf.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; + +namespace DevElf.Tests.DependencyInjection; + +[TestClass] +public class ServiceCollectionExtensionsTests +{ + #region AddWithFactoryFunc Tests + + [TestMethod] + public void AddWithFactoryFunc_registers_service_and_factory_function() + { + // Arrange + IServiceCollection services = new ServiceCollection(); + + // Act + _ = services.AddWithFactoryFunc(ServiceLifetime.Transient); + var provider = services.BuildServiceProvider(); + + // Assert + var service = provider.GetService(); + var factory = provider.GetService>(); + + _ = service.Should().NotBeNull(); + _ = factory.Should().NotBeNull(); + } + + [TestMethod] + public void AddWithFactoryFunc_factory_function_creates_service_instances() + { + // Arrange + IServiceCollection services = new ServiceCollection(); + _ = services.AddWithFactoryFunc(ServiceLifetime.Transient); + var provider = services.BuildServiceProvider(); + + // Act + var factory = provider.GetRequiredService>(); + var instance1 = factory(); + var instance2 = factory(); + + // Assert + _ = instance1.Should().NotBeNull(); + _ = instance2.Should().NotBeNull(); + _ = instance1.Should().NotBeSameAs(instance2); + } + + [TestMethod] + public void AddWithFactoryFunc_respects_service_lifetime() + { + // Arrange + IServiceCollection services = new ServiceCollection(); + _ = services.AddWithFactoryFunc(ServiceLifetime.Singleton); + var provider = services.BuildServiceProvider(); + + // Act + var service1 = provider.GetRequiredService(); + var service2 = provider.GetRequiredService(); + + // Assert + _ = service1.Should().BeSameAs(service2); + } + + [TestMethod] + public void AddWithFactoryFunc_throws_ArgumentNullException_when_services_is_null() + { + // Arrange + IServiceCollection? services = null; + + // Act + Action act = () => ServiceCollectionExtensions.AddWithFactoryFunc( + services!, + ServiceLifetime.Transient); + + // Assert + _ = act.Should().Throw() + .WithParameterName(nameof(services)); + } + + #endregion + + #region AddWithFactoryFunc with Factory Tests + + [TestMethod] + public void AddWithFactoryFunc_with_factory_registers_service_and_factory_function() + { + // Arrange + var fixture = new Fixture(); + string testValue = fixture.Create(); + IServiceCollection services = new ServiceCollection(); + + // Act + _ = services.AddWithFactoryFunc( + sp => new TestService { Value = testValue }, + ServiceLifetime.Transient); + var provider = services.BuildServiceProvider(); + + // Assert + var service = provider.GetRequiredService(); + var factory = provider.GetRequiredService>(); + + _ = service.Should().NotBeNull(); + _ = service.Value.Should().Be(testValue); + _ = factory.Should().NotBeNull(); + } + + [TestMethod] + public void AddWithFactoryFunc_with_factory_creates_instances_using_provided_factory() + { + // Arrange + var fixture = new Fixture(); + string testValue = fixture.Create(); + IServiceCollection services = new ServiceCollection(); + _ = services.AddWithFactoryFunc( + sp => new TestService { Value = testValue }, + ServiceLifetime.Transient); + var provider = services.BuildServiceProvider(); + + // Act + var factory = provider.GetRequiredService>(); + var instance = factory(); + + // Assert + _ = instance.Value.Should().Be(testValue); + } + + [TestMethod] + public void AddWithFactoryFunc_with_factory_throws_ArgumentNullException_when_services_is_null() + { + // Arrange + IServiceCollection? services = null; + + // Act + Action act = () => ServiceCollectionExtensions.AddWithFactoryFunc( + services!, + sp => new TestService(), + ServiceLifetime.Transient); + + // Assert + _ = act.Should().Throw() + .WithParameterName(nameof(services)); + } + + [TestMethod] + public void AddWithFactoryFunc_with_factory_throws_ArgumentNullException_when_factory_is_null() + { + // Arrange + IServiceCollection services = new ServiceCollection(); + Func? serviceFactory = null; + + // Act + Action act = () => services.AddWithFactoryFunc( + serviceFactory!, + ServiceLifetime.Transient); + + // Assert + _ = act.Should().Throw() + .WithParameterName(nameof(serviceFactory)); + } + + #endregion + + #region AddWithFactoryFunc Tests + + [TestMethod] + public void AddWithFactoryFunc_with_implementation_registers_service_and_factory_function() + { + // Arrange + IServiceCollection services = new ServiceCollection(); + + // Act + _ = services.AddWithFactoryFunc(ServiceLifetime.Scoped); + var provider = services.BuildServiceProvider(); + + // Assert + var service = provider.GetService(); + var factory = provider.GetService>(); + + _ = service.Should().NotBeNull(); + _ = service.Should().BeOfType(); + _ = factory.Should().NotBeNull(); + } + + [TestMethod] + public void AddWithFactoryFunc_with_implementation_factory_creates_correct_implementation() + { + // Arrange + IServiceCollection services = new ServiceCollection(); + _ = services.AddWithFactoryFunc(ServiceLifetime.Transient); + var provider = services.BuildServiceProvider(); + + // Act + var factory = provider.GetRequiredService>(); + var instance = factory(); + + // Assert + _ = instance.Should().BeOfType(); + } + + [TestMethod] + public void AddWithFactoryFunc_with_implementation_throws_ArgumentNullException_when_services_is_null() + { + // Arrange + IServiceCollection? services = null; + + // Act + Action act = () => ServiceCollectionExtensions.AddWithFactoryFunc( + services!, + ServiceLifetime.Transient); + + // Assert + _ = act.Should().Throw() + .WithParameterName(nameof(services)); + } + + #endregion + + #region TryAddWithFactoryFunc Tests + + [TestMethod] + public void TryAddWithFactoryFunc_registers_service_when_not_already_registered() + { + // Arrange + IServiceCollection services = new ServiceCollection(); + + // Act + _ = services.TryAddWithFactoryFunc(ServiceLifetime.Transient); + var provider = services.BuildServiceProvider(); + + // Assert + var service = provider.GetService(); + var factory = provider.GetService>(); + + _ = service.Should().NotBeNull(); + _ = factory.Should().NotBeNull(); + } + + [TestMethod] + public void TryAddWithFactoryFunc_does_not_replace_existing_registration() + { + // Arrange + var fixture = new Fixture(); + string firstValue = fixture.Create(); + IServiceCollection services = new ServiceCollection(); + + _ = services.AddSingleton(new TestService { Value = firstValue }); + + // Act + _ = services.TryAddWithFactoryFunc(ServiceLifetime.Singleton); + var provider = services.BuildServiceProvider(); + var service = provider.GetRequiredService(); + + // Assert + _ = service.Value.Should().Be(firstValue); + } + + [TestMethod] + public void TryAddWithFactoryFunc_throws_ArgumentNullException_when_services_is_null() + { + // Arrange + IServiceCollection? services = null; + + // Act + Action act = () => ServiceCollectionExtensions.TryAddWithFactoryFunc( + services!, + ServiceLifetime.Transient); + + // Assert + _ = act.Should().Throw() + .WithParameterName(nameof(services)); + } + + #endregion + + #region TryAddWithFactoryFunc with Factory Tests + + [TestMethod] + public void TryAddWithFactoryFunc_with_factory_registers_service_when_not_already_registered() + { + // Arrange + var fixture = new Fixture(); + string testValue = fixture.Create(); + IServiceCollection services = new ServiceCollection(); + + // Act + _ = services.TryAddWithFactoryFunc( + sp => new TestService { Value = testValue }, + ServiceLifetime.Transient); + var provider = services.BuildServiceProvider(); + + // Assert + var service = provider.GetRequiredService(); + _ = service.Value.Should().Be(testValue); + } + + [TestMethod] + public void TryAddWithFactoryFunc_with_factory_does_not_replace_existing_registration() + { + // Arrange + var fixture = new Fixture(); + string firstValue = fixture.Create(); + string secondValue = fixture.Create(); + IServiceCollection services = new ServiceCollection(); + + _ = services.AddSingleton(new TestService { Value = firstValue }); + + // Act + _ = services.TryAddWithFactoryFunc( + sp => new TestService { Value = secondValue }, + ServiceLifetime.Singleton); + var provider = services.BuildServiceProvider(); + var service = provider.GetRequiredService(); + + // Assert + _ = service.Value.Should().Be(firstValue); + } + + [TestMethod] + public void TryAddWithFactoryFunc_with_factory_throws_ArgumentNullException_when_services_is_null() + { + // Arrange + IServiceCollection? services = null; + + // Act + Action act = () => ServiceCollectionExtensions.TryAddWithFactoryFunc( + services!, + sp => new TestService(), + ServiceLifetime.Transient); + + // Assert + _ = act.Should().Throw() + .WithParameterName(nameof(services)); + } + + [TestMethod] + public void TryAddWithFactoryFunc_with_factory_throws_ArgumentNullException_when_factory_is_null() + { + // Arrange + IServiceCollection services = new ServiceCollection(); + Func? serviceFactory = null; + + // Act + Action act = () => services.TryAddWithFactoryFunc( + serviceFactory!, + ServiceLifetime.Transient); + + // Assert + _ = act.Should().Throw() + .WithParameterName(nameof(serviceFactory)); + } + + #endregion + + #region TryAddWithFactoryFunc Tests + + [TestMethod] + public void TryAddWithFactoryFunc_with_implementation_registers_service_when_not_already_registered() + { + // Arrange + IServiceCollection services = new ServiceCollection(); + + // Act + _ = services.TryAddWithFactoryFunc(ServiceLifetime.Scoped); + var provider = services.BuildServiceProvider(); + + // Assert + var service = provider.GetRequiredService(); + _ = service.Should().BeOfType(); + } + + [TestMethod] + public void TryAddWithFactoryFunc_with_implementation_does_not_replace_existing_registration() + { + // Arrange + IServiceCollection services = new ServiceCollection(); + _ = services.AddSingleton(); + + // Act + _ = services.TryAddWithFactoryFunc(ServiceLifetime.Singleton); + var provider = services.BuildServiceProvider(); + var service = provider.GetRequiredService(); + + // Assert + _ = service.Should().BeOfType(); + } + + [TestMethod] + public void TryAddWithFactoryFunc_with_implementation_throws_ArgumentNullException_when_services_is_null() + { + // Arrange + IServiceCollection? services = null; + + // Act + Action act = () => ServiceCollectionExtensions.TryAddWithFactoryFunc( + services!, + ServiceLifetime.Transient); + + // Assert + _ = act.Should().Throw() + .WithParameterName(nameof(services)); + } + + #endregion + + #region AddFactoryFunc Tests + + [TestMethod] + public void AddFactoryFunc_registers_factory_function() + { + // Arrange + IServiceCollection services = new ServiceCollection(); + _ = services.AddTransient(); + + // Act + _ = services.AddFactoryFunc(ServiceLifetime.Singleton); + var provider = services.BuildServiceProvider(); + + // Assert + var factory = provider.GetService>(); + _ = factory.Should().NotBeNull(); + } + + [TestMethod] + public void AddFactoryFunc_factory_creates_instances_from_service_provider() + { + // Arrange + IServiceCollection services = new ServiceCollection(); + _ = services.AddTransient(); + _ = services.AddFactoryFunc(ServiceLifetime.Singleton); + var provider = services.BuildServiceProvider(); + + // Act + var factory = provider.GetRequiredService>(); + var instance1 = factory(); + var instance2 = factory(); + + // Assert + _ = instance1.Should().NotBeNull(); + _ = instance2.Should().NotBeNull(); + _ = instance1.Should().NotBeSameAs(instance2); + } + + [TestMethod] + public void AddFactoryFunc_throws_ArgumentNullException_when_services_is_null() + { + // Arrange + IServiceCollection? services = null; + + // Act + Action act = () => services!.AddFactoryFunc(ServiceLifetime.Singleton); + + // Assert + _ = act.Should().Throw() + .WithParameterName(nameof(services)); + } + + #endregion + + #region AddFactoryFunc with Custom Factory Tests + + [TestMethod] + public void AddFactoryFunc_with_custom_factory_registers_factory_function() + { + // Arrange + var fixture = new Fixture(); + string testValue = fixture.Create(); + IServiceCollection services = new ServiceCollection(); + + // Act + _ = services.AddFactoryFunc( + sp => new TestService { Value = testValue }, + ServiceLifetime.Singleton); + var provider = services.BuildServiceProvider(); + + // Assert + var factory = provider.GetRequiredService>(); + var instance = factory(); + _ = instance.Value.Should().Be(testValue); + } + + [TestMethod] + public void AddFactoryFunc_with_custom_factory_throws_ArgumentNullException_when_services_is_null() + { + // Arrange + IServiceCollection? services = null; + + // Act + Action act = () => services!.AddFactoryFunc( + sp => new TestService(), + ServiceLifetime.Singleton); + + // Assert + _ = act.Should().Throw() + .WithParameterName(nameof(services)); + } + + [TestMethod] + public void AddFactoryFunc_with_custom_factory_throws_ArgumentNullException_when_factory_is_null() + { + // Arrange + IServiceCollection services = new ServiceCollection(); + Func? serviceFactory = null; + + // Act + Action act = () => services.AddFactoryFunc( + serviceFactory!, + ServiceLifetime.Singleton); + + // Assert + _ = act.Should().Throw() + .WithParameterName(nameof(serviceFactory)); + } + + #endregion + + #region TryAddFactoryFunc Tests + + [TestMethod] + public void TryAddFactoryFunc_registers_factory_when_not_already_registered() + { + // Arrange + IServiceCollection services = new ServiceCollection(); + _ = services.AddTransient(); + + // Act + _ = services.TryAddFactoryFunc(ServiceLifetime.Singleton); + var provider = services.BuildServiceProvider(); + + // Assert + var factory = provider.GetService>(); + _ = factory.Should().NotBeNull(); + } + + [TestMethod] + public void TryAddFactoryFunc_does_not_replace_existing_factory_registration() + { + // Arrange + var fixture = new Fixture(); + string firstValue = fixture.Create(); + IServiceCollection services = new ServiceCollection(); + + _ = services.AddSingleton>(() => new TestService { Value = firstValue }); + + // Act + _ = services.TryAddFactoryFunc(ServiceLifetime.Singleton); + var provider = services.BuildServiceProvider(); + var factory = provider.GetRequiredService>(); + var instance = factory(); + + // Assert + _ = instance.Value.Should().Be(firstValue); + } + + [TestMethod] + public void TryAddFactoryFunc_throws_ArgumentNullException_when_services_is_null() + { + // Arrange + IServiceCollection? services = null; + + // Act + Action act = () => services!.TryAddFactoryFunc(ServiceLifetime.Singleton); + + // Assert + _ = act.Should().Throw() + .WithParameterName(nameof(services)); + } + + #endregion + + #region TryAddFactoryFunc with Custom Factory Tests + + [TestMethod] + public void TryAddFactoryFunc_with_custom_factory_registers_factory_when_not_already_registered() + { + // Arrange + var fixture = new Fixture(); + string testValue = fixture.Create(); + IServiceCollection services = new ServiceCollection(); + + // Act + _ = services.TryAddFactoryFunc( + sp => new TestService { Value = testValue }, + ServiceLifetime.Singleton); + var provider = services.BuildServiceProvider(); + + // Assert + var factory = provider.GetRequiredService>(); + var instance = factory(); + _ = instance.Value.Should().Be(testValue); + } + + [TestMethod] + public void TryAddFactoryFunc_with_custom_factory_does_not_replace_existing_factory_registration() + { + // Arrange + var fixture = new Fixture(); + string firstValue = fixture.Create(); + string secondValue = fixture.Create(); + IServiceCollection services = new ServiceCollection(); + + _ = services.AddSingleton>(() => new TestService { Value = firstValue }); + + // Act + _ = services.TryAddFactoryFunc( + sp => new TestService { Value = secondValue }, + ServiceLifetime.Singleton); + var provider = services.BuildServiceProvider(); + var factory = provider.GetRequiredService>(); + var instance = factory(); + + // Assert + _ = instance.Value.Should().Be(firstValue); + } + + [TestMethod] + public void TryAddFactoryFunc_with_custom_factory_throws_ArgumentNullException_when_services_is_null() + { + // Arrange + IServiceCollection? services = null; + + // Act + Action act = () => services!.TryAddFactoryFunc( + sp => new TestService(), + ServiceLifetime.Singleton); + + // Assert + _ = act.Should().Throw() + .WithParameterName(nameof(services)); + } + + [TestMethod] + public void TryAddFactoryFunc_with_custom_factory_throws_ArgumentNullException_when_factory_is_null() + { + // Arrange + IServiceCollection services = new ServiceCollection(); + Func? serviceFactory = null; + + // Act + Action act = () => services.TryAddFactoryFunc( + serviceFactory!, + ServiceLifetime.Singleton); + + // Assert + _ = act.Should().Throw() + .WithParameterName(nameof(serviceFactory)); + } + + #endregion + + #region Add Tests + + [TestMethod] + public void Add_registers_service_with_specified_lifetime() + { + // Arrange + IServiceCollection services = new ServiceCollection(); + + // Act + _ = services.Add(ServiceLifetime.Transient); + var provider = services.BuildServiceProvider(); + + // Assert + var service1 = provider.GetRequiredService(); + var service2 = provider.GetRequiredService(); + + _ = service1.Should().NotBeNull(); + _ = service2.Should().NotBeNull(); + _ = service1.Should().NotBeSameAs(service2); + } + + [TestMethod] + public void Add_allows_multiple_registrations_of_same_service() + { + // Arrange + IServiceCollection services = new ServiceCollection(); + + // Act + _ = services.Add(ServiceLifetime.Transient); + _ = services.Add(ServiceLifetime.Transient); + + // Assert + _ = services.Count.Should().Be(2); + } + + [TestMethod] + public void Add_throws_ArgumentNullException_when_services_is_null() + { + // Arrange + IServiceCollection? services = null; + + // Act + Action act = () => services!.Add(ServiceLifetime.Transient); + + // Assert + _ = act.Should().Throw() + .WithParameterName(nameof(services)); + } + + #endregion + + #region Add with Factory Tests + + [TestMethod] + public void Add_with_factory_registers_service_using_factory() + { + // Arrange + var fixture = new Fixture(); + string testValue = fixture.Create(); + IServiceCollection services = new ServiceCollection(); + + // Act + _ = services.Add( + sp => new TestService { Value = testValue }, + ServiceLifetime.Transient); + var provider = services.BuildServiceProvider(); + + // Assert + var service = provider.GetRequiredService(); + _ = service.Value.Should().Be(testValue); + } + + [TestMethod] + public void Add_with_factory_throws_ArgumentNullException_when_services_is_null() + { + // Arrange + IServiceCollection? services = null; + + // Act + Action act = () => services!.Add( + sp => new TestService(), + ServiceLifetime.Transient); + + // Assert + _ = act.Should().Throw() + .WithParameterName(nameof(services)); + } + + [TestMethod] + public void Add_with_factory_throws_ArgumentNullException_when_factory_is_null() + { + // Arrange + IServiceCollection services = new ServiceCollection(); + Func? serviceFactory = null; + + // Act + Action act = () => services.Add( + serviceFactory!, + ServiceLifetime.Transient); + + // Assert + _ = act.Should().Throw() + .WithParameterName(nameof(serviceFactory)); + } + + #endregion + + #region Add Tests + + [TestMethod] + public void Add_with_implementation_registers_service_with_implementation_type() + { + // Arrange + IServiceCollection services = new ServiceCollection(); + + // Act + _ = services.Add(ServiceLifetime.Transient); + var provider = services.BuildServiceProvider(); + + // Assert + var service = provider.GetRequiredService(); + _ = service.Should().BeOfType(); + } + + [TestMethod] + public void Add_with_implementation_respects_service_lifetime() + { + // Arrange + IServiceCollection services = new ServiceCollection(); + + // Act + _ = services.Add(ServiceLifetime.Singleton); + var provider = services.BuildServiceProvider(); + + // Assert + var service1 = provider.GetRequiredService(); + var service2 = provider.GetRequiredService(); + _ = service1.Should().BeSameAs(service2); + } + + [TestMethod] + public void Add_with_implementation_throws_ArgumentNullException_when_services_is_null() + { + // Arrange + IServiceCollection? services = null; + + // Act + Action act = () => services!.Add(ServiceLifetime.Transient); + + // Assert + _ = act.Should().Throw() + .WithParameterName(nameof(services)); + } + + #endregion + + #region TryAdd Tests + + [TestMethod] + public void TryAdd_registers_service_when_not_already_registered() + { + // Arrange + IServiceCollection services = new ServiceCollection(); + + // Act + _ = services.TryAdd(ServiceLifetime.Transient); + var provider = services.BuildServiceProvider(); + + // Assert + var service = provider.GetRequiredService(); + _ = service.Should().NotBeNull(); + } + + [TestMethod] + public void TryAdd_does_not_register_service_when_already_registered() + { + // Arrange + var fixture = new Fixture(); + string firstValue = fixture.Create(); + IServiceCollection services = new ServiceCollection(); + + _ = services.AddSingleton(new TestService { Value = firstValue }); + + // Act + _ = services.TryAdd(ServiceLifetime.Singleton); + var provider = services.BuildServiceProvider(); + var service = provider.GetRequiredService(); + + // Assert + _ = service.Value.Should().Be(firstValue); + } + + [TestMethod] + public void TryAdd_throws_ArgumentNullException_when_services_is_null() + { + // Arrange + IServiceCollection? services = null; + + // Act + Action act = () => services!.TryAdd(ServiceLifetime.Transient); + + // Assert + _ = act.Should().Throw() + .WithParameterName(nameof(services)); + } + + #endregion + + #region TryAdd with Factory Tests + + [TestMethod] + public void TryAdd_with_factory_registers_service_when_not_already_registered() + { + // Arrange + var fixture = new Fixture(); + string testValue = fixture.Create(); + IServiceCollection services = new ServiceCollection(); + + // Act + _ = services.TryAdd( + sp => new TestService { Value = testValue }, + ServiceLifetime.Transient); + var provider = services.BuildServiceProvider(); + + // Assert + var service = provider.GetRequiredService(); + _ = service.Value.Should().Be(testValue); + } + + [TestMethod] + public void TryAdd_with_factory_does_not_register_service_when_already_registered() + { + // Arrange + var fixture = new Fixture(); + string firstValue = fixture.Create(); + string secondValue = fixture.Create(); + IServiceCollection services = new ServiceCollection(); + + _ = services.AddSingleton(new TestService { Value = firstValue }); + + // Act + _ = services.TryAdd( + sp => new TestService { Value = secondValue }, + ServiceLifetime.Singleton); + var provider = services.BuildServiceProvider(); + var service = provider.GetRequiredService(); + + // Assert + _ = service.Value.Should().Be(firstValue); + } + + [TestMethod] + public void TryAdd_with_factory_throws_ArgumentNullException_when_services_is_null() + { + // Arrange + IServiceCollection? services = null; + + // Act + Action act = () => services!.TryAdd( + sp => new TestService(), + ServiceLifetime.Transient); + + // Assert + _ = act.Should().Throw() + .WithParameterName(nameof(services)); + } + + [TestMethod] + public void TryAdd_with_factory_throws_ArgumentNullException_when_factory_is_null() + { + // Arrange + IServiceCollection services = new ServiceCollection(); + Func? serviceFactory = null; + + // Act + Action act = () => services.TryAdd( + serviceFactory!, + ServiceLifetime.Transient); + + // Assert + _ = act.Should().Throw() + .WithParameterName(nameof(serviceFactory)); + } + + #endregion + + #region TryAdd Tests + + [TestMethod] + public void TryAdd_with_implementation_registers_service_when_not_already_registered() + { + // Arrange + IServiceCollection services = new ServiceCollection(); + + // Act + _ = services.TryAdd(ServiceLifetime.Transient); + var provider = services.BuildServiceProvider(); + + // Assert + var service = provider.GetRequiredService(); + _ = service.Should().BeOfType(); + } + + [TestMethod] + public void TryAdd_with_implementation_does_not_register_service_when_already_registered() + { + // Arrange + IServiceCollection services = new ServiceCollection(); + _ = services.AddSingleton(); + + // Act + _ = services.TryAdd(ServiceLifetime.Singleton); + var provider = services.BuildServiceProvider(); + var service = provider.GetRequiredService(); + + // Assert + _ = service.Should().BeOfType(); + } + + [TestMethod] + public void TryAdd_with_implementation_throws_ArgumentNullException_when_services_is_null() + { + // Arrange + IServiceCollection? services = null; + + // Act + Action act = () => services!.TryAdd(ServiceLifetime.Transient); + + // Assert + _ = act.Should().Throw() + .WithParameterName(nameof(services)); + } + + #endregion + + #region Method Chaining Tests + + [TestMethod] + public void AddWithFactoryFunc_returns_service_collection_for_chaining() + { + // Arrange + IServiceCollection services = new ServiceCollection(); + + // Act + IServiceCollection result = services + .AddWithFactoryFunc(ServiceLifetime.Transient) + .AddWithFactoryFunc(ServiceLifetime.Scoped); + + // Assert + _ = result.Should().BeSameAs(services); + _ = services.Count.Should().BeGreaterThan(0); + } + + [TestMethod] + public void TryAddWithFactoryFunc_returns_service_collection_for_chaining() + { + // Arrange + IServiceCollection services = new ServiceCollection(); + + // Act + IServiceCollection result = services + .TryAddWithFactoryFunc(ServiceLifetime.Transient) + .TryAddWithFactoryFunc(ServiceLifetime.Scoped); + + // Assert + _ = result.Should().BeSameAs(services); + } + + [TestMethod] + public void Add_methods_return_service_collection_for_chaining() + { + // Arrange + IServiceCollection services = new ServiceCollection(); + + // Act + IServiceCollection result = services + .Add(ServiceLifetime.Transient) + .Add(ServiceLifetime.Scoped); + + // Assert + _ = result.Should().BeSameAs(services); + } + + [TestMethod] + public void TryAdd_methods_return_service_collection_for_chaining() + { + // Arrange + IServiceCollection services = new ServiceCollection(); + + // Act + IServiceCollection result = services + .TryAdd(ServiceLifetime.Transient) + .TryAdd(ServiceLifetime.Scoped); + + // Assert + _ = result.Should().BeSameAs(services); + } + + #endregion + + #region Complex Scenarios + + [TestMethod] + public void AddWithFactoryFunc_allows_injecting_dependencies_into_created_instances() + { + // Arrange + var fixture = new Fixture(); + string dependencyValue = fixture.Create(); + IServiceCollection services = new ServiceCollection(); + + _ = services.AddSingleton(new TestDependency { Value = dependencyValue }); + _ = services.AddWithFactoryFunc(ServiceLifetime.Transient); + + var provider = services.BuildServiceProvider(); + + // Act + var service = provider.GetRequiredService(); + + // Assert + _ = service.Dependency.Should().NotBeNull(); + _ = service.Dependency.Value.Should().Be(dependencyValue); + } + + [TestMethod] + public void Factory_function_uses_scoped_lifetime_appropriately() + { + // Arrange + IServiceCollection services = new ServiceCollection(); + _ = services.AddWithFactoryFunc(ServiceLifetime.Scoped); + var provider = services.BuildServiceProvider(); + + // Act + using IServiceScope scope1 = provider.CreateScope(); + using IServiceScope scope2 = provider.CreateScope(); + + var service1a = scope1.ServiceProvider.GetRequiredService(); + var service1b = scope1.ServiceProvider.GetRequiredService(); + var service2a = scope2.ServiceProvider.GetRequiredService(); + + // Assert + _ = service1a.Should().BeSameAs(service1b); + _ = service1a.Should().NotBeSameAs(service2a); + } + + [TestMethod] + public void Multiple_services_can_be_registered_with_different_lifetimes() + { + // Arrange + IServiceCollection services = new ServiceCollection(); + + // Act + _ = services + .AddWithFactoryFunc(ServiceLifetime.Singleton) + .AddWithFactoryFunc(ServiceLifetime.Scoped); + + var provider = services.BuildServiceProvider(); + + // Assert + var singleton1 = provider.GetRequiredService(); + var singleton2 = provider.GetRequiredService(); + + using IServiceScope scope1 = provider.CreateScope(); + using IServiceScope scope2 = provider.CreateScope(); + + var scoped1 = scope1.ServiceProvider.GetRequiredService(); + var scoped2 = scope2.ServiceProvider.GetRequiredService(); + + _ = singleton1.Should().BeSameAs(singleton2); + _ = scoped1.Should().NotBeSameAs(scoped2); + } + + #endregion + + #region Helper Types + + private class TestService + { + public string Value { get; set; } = string.Empty; + } + + private interface ITestService + { + } + + private class TestServiceImpl : ITestService + { + } + + private class AlternateTestServiceImpl : ITestService + { + } + + private class TestDependency + { + public string Value { get; set; } = string.Empty; + } + + private class TestServiceWithDependency(TestDependency dependency) + { + public TestDependency Dependency { get; } = dependency; + } + + #endregion +} diff --git a/tests/DevElf.Tests/DevElf.Tests.csproj b/tests/DevElf.Tests/DevElf.Tests.csproj index 6f70334..1d35128 100644 --- a/tests/DevElf.Tests/DevElf.Tests.csproj +++ b/tests/DevElf.Tests/DevElf.Tests.csproj @@ -8,6 +8,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all + diff --git a/tests/DevElf.Tests/Threading/RateLimiting/NoLimitRateLimiterTests.cs b/tests/DevElf.Tests/Threading/RateLimiting/NoLimitRateLimiterTests.cs new file mode 100644 index 0000000..38b9d03 --- /dev/null +++ b/tests/DevElf.Tests/Threading/RateLimiting/NoLimitRateLimiterTests.cs @@ -0,0 +1,339 @@ +using System.Threading.RateLimiting; +using AwesomeAssertions; +using DevElf.Threading.RateLimiting; + +namespace DevElf.Tests.Threading.RateLimiting; + +[TestClass] +public class NoLimitRateLimiterTests +{ + public TestContext TestContext { get; set; } = null!; + + [TestMethod] + public void Instance_returns_singleton_instance() + { + // Arrange & Act + var instance1 = NoLimitRateLimiter.Instance; + var instance2 = NoLimitRateLimiter.Instance; + + // Assert + _ = instance1.Should().BeSameAs(instance2); + } + + [TestMethod] + public void IdleDuration_returns_null() + { + // Arrange + var limiter = NoLimitRateLimiter.Instance; + + // Act + TimeSpan? idleDuration = limiter.IdleDuration; + + // Assert + _ = idleDuration.Should().BeNull(); + } + + [TestMethod] + public void GetStatistics_returns_null() + { + // Arrange + var limiter = NoLimitRateLimiter.Instance; + + // Act + RateLimiterStatistics? statistics = limiter.GetStatistics(); + + // Assert + _ = statistics.Should().BeNull(); + } + + [TestMethod] + public async Task AcquireAsync_always_succeeds_with_single_permit() + { + // Arrange + var limiter = NoLimitRateLimiter.Instance; + + // Act + using var lease = await limiter.AcquireAsync(1, TestContext.CancellationToken); + + // Assert + _ = lease.IsAcquired.Should().BeTrue(); + } + + [TestMethod] + public async Task AcquireAsync_always_succeeds_with_multiple_permits() + { + // Arrange + var limiter = NoLimitRateLimiter.Instance; + + // Act + using var lease = await limiter.AcquireAsync(100, TestContext.CancellationToken); + + // Assert + _ = lease.IsAcquired.Should().BeTrue(); + } + + [TestMethod] + public async Task AcquireAsync_always_succeeds_with_zero_permits() + { + // Arrange + var limiter = NoLimitRateLimiter.Instance; + + // Act + using var lease = await limiter.AcquireAsync(0, TestContext.CancellationToken); + + // Assert + _ = lease.IsAcquired.Should().BeTrue(); + } + + [TestMethod] + public async Task AcquireAsync_succeeds_immediately_without_waiting() + { + // Arrange + var limiter = NoLimitRateLimiter.Instance; + var stopwatch = System.Diagnostics.Stopwatch.StartNew(); + + // Act + using var lease = await limiter.AcquireAsync(1000, TestContext.CancellationToken); + stopwatch.Stop(); + + // Assert + _ = lease.IsAcquired.Should().BeTrue(); + _ = stopwatch.ElapsedMilliseconds.Should().BeLessThan(100); + } + + [TestMethod] + public async Task AcquireAsync_can_acquire_multiple_leases_concurrently() + { + // Arrange + var limiter = NoLimitRateLimiter.Instance; + + // Act + using var lease1 = await limiter.AcquireAsync(50, TestContext.CancellationToken); + using var lease2 = await limiter.AcquireAsync(50, TestContext.CancellationToken); + using var lease3 = await limiter.AcquireAsync(50, TestContext.CancellationToken); + + // Assert + _ = lease1.IsAcquired.Should().BeTrue(); + _ = lease2.IsAcquired.Should().BeTrue(); + _ = lease3.IsAcquired.Should().BeTrue(); + } + + [TestMethod] + public void AttemptAcquire_always_succeeds_with_single_permit() + { + // Arrange + var limiter = NoLimitRateLimiter.Instance; + + // Act + using var lease = limiter.AttemptAcquire(1); + + // Assert + _ = lease.IsAcquired.Should().BeTrue(); + } + + [TestMethod] + public void AttemptAcquire_always_succeeds_with_multiple_permits() + { + // Arrange + var limiter = NoLimitRateLimiter.Instance; + + // Act + using var lease = limiter.AttemptAcquire(100); + + // Assert + _ = lease.IsAcquired.Should().BeTrue(); + } + + [TestMethod] + public void AttemptAcquire_always_succeeds_with_zero_permits() + { + // Arrange + var limiter = NoLimitRateLimiter.Instance; + + // Act + using var lease = limiter.AttemptAcquire(0); + + // Assert + _ = lease.IsAcquired.Should().BeTrue(); + } + + [TestMethod] + public void AttemptAcquire_can_acquire_multiple_leases_concurrently() + { + // Arrange + var limiter = NoLimitRateLimiter.Instance; + + // Act + using var lease1 = limiter.AttemptAcquire(50); + using var lease2 = limiter.AttemptAcquire(50); + using var lease3 = limiter.AttemptAcquire(50); + + // Assert + _ = lease1.IsAcquired.Should().BeTrue(); + _ = lease2.IsAcquired.Should().BeTrue(); + _ = lease3.IsAcquired.Should().BeTrue(); + } + + [TestMethod] + public async Task Lease_MetadataNames_returns_empty_collection() + { + // Arrange + var limiter = NoLimitRateLimiter.Instance; + using var lease = await limiter.AcquireAsync(1, TestContext.CancellationToken); + + // Act + var metadataNames = lease.MetadataNames.ToList(); + + // Assert + _ = metadataNames.Should().BeEmpty(); + } + + [TestMethod] + public async Task Lease_TryGetMetadata_always_returns_false() + { + // Arrange + var limiter = NoLimitRateLimiter.Instance; + using var lease = await limiter.AcquireAsync(1, TestContext.CancellationToken); + + // Act + bool result = lease.TryGetMetadata("SomeKey", out object? metadata); + + // Assert + _ = result.Should().BeFalse(); + _ = metadata.Should().BeNull(); + } + + [TestMethod] + public async Task Lease_TryGetMetadata_returns_false_for_any_key() + { + // Arrange + var limiter = NoLimitRateLimiter.Instance; + using var lease = await limiter.AcquireAsync(1, TestContext.CancellationToken); + + // Act & Assert + _ = lease.TryGetMetadata("Key1", out object? metadata1).Should().BeFalse(); + _ = metadata1.Should().BeNull(); + + _ = lease.TryGetMetadata("Key2", out object? metadata2).Should().BeFalse(); + _ = metadata2.Should().BeNull(); + + _ = lease.TryGetMetadata(string.Empty, out object? metadata3).Should().BeFalse(); + _ = metadata3.Should().BeNull(); + } + + [TestMethod] + public async Task Lease_can_be_disposed_multiple_times_safely() + { + // Arrange + var limiter = NoLimitRateLimiter.Instance; + var lease = await limiter.AcquireAsync(1, TestContext.CancellationToken); + + // Act & Assert: disposing multiple times should not throw + lease.Dispose(); + lease.Dispose(); + lease.Dispose(); + } + + [TestMethod] + public async Task Multiple_leases_share_same_instance() + { + // Arrange + var limiter = NoLimitRateLimiter.Instance; + + // Act + using var lease1 = await limiter.AcquireAsync(1, TestContext.CancellationToken); + using var lease2 = await limiter.AcquireAsync(1, TestContext.CancellationToken); + + // Assert: the leases should be the same singleton instance + _ = lease1.Should().BeSameAs(lease2); + } + + [TestMethod] + public async Task AcquireAsync_completes_synchronously() + { + // Arrange + var limiter = NoLimitRateLimiter.Instance; + + // Act + ValueTask task = limiter.AcquireAsync(1, TestContext.CancellationToken); + + // Assert: should be completed synchronously + _ = task.IsCompleted.Should().BeTrue(); + + using var lease = await task; + _ = lease.IsAcquired.Should().BeTrue(); + } + + [TestMethod] + public async Task Works_with_RateLimiterExtensions_ApplyToAsync_action() + { + // Arrange + var limiter = NoLimitRateLimiter.Instance; + bool actionExecuted = false; + + // Act + await limiter.ApplyToAsync( + _ => + { + actionExecuted = true; + + return Task.CompletedTask; + }, + permitCount: 100, + cancellationToken: TestContext.CancellationToken); + + // Assert + _ = actionExecuted.Should().BeTrue(); + } + + [TestMethod] + public async Task Works_with_RateLimiterExtensions_ApplyToAsync_request() + { + // Arrange + var limiter = NoLimitRateLimiter.Instance; + + // Act + int result = await limiter.ApplyToAsync( + _ => Task.FromResult(42), + permitCount: 100, + cancellationToken: TestContext.CancellationToken); + + // Assert + _ = result.Should().Be(42); + } + + [TestMethod] + public async Task Supports_high_concurrency_without_blocking() + { + // Arrange + var limiter = NoLimitRateLimiter.Instance; + int taskCount = 100; + int executionCount = 0; + + // Act + var tasks = Enumerable.Range(0, taskCount) + .Select(async _ => + { + using var lease = await limiter.AcquireAsync(10, TestContext.CancellationToken); + _ = Interlocked.Increment(ref executionCount); + }); + + await Task.WhenAll(tasks); + + // Assert + _ = executionCount.Should().Be(taskCount); + } + + [TestMethod] + public void Can_create_new_instance_separate_from_singleton() + { + // Arrange & Act + var instance1 = NoLimitRateLimiter.Instance; + var instance2 = new NoLimitRateLimiter(); + + // Assert: they should be different instances but behave identically + _ = instance1.Should().NotBeSameAs(instance2); + _ = instance1.IdleDuration.Should().Be(instance2.IdleDuration); + _ = instance1.GetStatistics().Should().Be(instance2.GetStatistics()); + } +} diff --git a/tests/DevElf.Tests/Threading/RateLimiting/RateLimiterExtensionsTests.cs b/tests/DevElf.Tests/Threading/RateLimiting/RateLimiterExtensionsTests.cs new file mode 100644 index 0000000..972f3e4 --- /dev/null +++ b/tests/DevElf.Tests/Threading/RateLimiting/RateLimiterExtensionsTests.cs @@ -0,0 +1,607 @@ +using System.Threading.RateLimiting; +using AwesomeAssertions; +using DevElf.Threading.RateLimiting; + +namespace DevElf.Tests.Threading.RateLimiting; + +[TestClass] +public class RateLimiterExtensionsTests +{ + public TestContext TestContext { get; set; } = null!; + + [TestMethod] + public async Task ApplyToAsync_action_throws_ArgumentNullException_when_limiter_is_null() + { + // Arrange + RateLimiter limiter = null!; + Func action = _ => Task.CompletedTask; + + // Act + var act = async () => await limiter.ApplyToAsync(action, cancellationToken: TestContext.CancellationToken); + + // Assert + _ = await act.Should().ThrowAsync(); + } + + [TestMethod] + public async Task ApplyToAsync_action_throws_ArgumentNullException_when_action_is_null() + { + // Arrange + using var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions + { + PermitLimit = 1, + QueueLimit = 0 + }); + + Func action = null!; + + // Act + var act = async () => await limiter.ApplyToAsync(action, cancellationToken: TestContext.CancellationToken); + + // Assert + _ = await act.Should().ThrowAsync(); + } + + [TestMethod] + public async Task ApplyToAsync_action_executes_action_when_permits_are_available() + { + // Arrange + using var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions + { + PermitLimit = 10, + QueueLimit = 0 + }); + + bool actionExecuted = false; + + // Act + await limiter.ApplyToAsync( + _ => + { + actionExecuted = true; + + return Task.CompletedTask; + }, + cancellationToken: TestContext.CancellationToken); + + // Assert + _ = actionExecuted.Should().BeTrue(); + } + + [TestMethod] + public async Task ApplyToAsync_action_acquires_and_releases_permit() + { + // Arrange + using var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions + { + PermitLimit = 1, + QueueLimit = 0 + }); + + // Act + await limiter.ApplyToAsync( + _ => Task.CompletedTask, + cancellationToken: TestContext.CancellationToken); + + // Assert: after execution, permit should be available again + using var lease = await limiter.AcquireAsync(1, TestContext.CancellationToken); + _ = lease.IsAcquired.Should().BeTrue(); + } + + [TestMethod] + public async Task ApplyToAsync_action_releases_permit_even_when_action_throws() + { + // Arrange + using var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions + { + PermitLimit = 1, + QueueLimit = 0 + }); + + // Act + var act = async () => await limiter.ApplyToAsync( + _ => throw new InvalidOperationException("Test exception"), + cancellationToken: TestContext.CancellationToken); + + // Assert + _ = await act.Should().ThrowAsync(); + + // verify permit is available again + using var lease = await limiter.AcquireAsync(1, TestContext.CancellationToken); + _ = lease.IsAcquired.Should().BeTrue(); + } + + [TestMethod] + public async Task ApplyToAsync_action_waits_and_retries_when_permits_not_immediately_available() + { + // Arrange + using var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions + { + PermitLimit = 1, + QueueLimit = 0 + }); + + // acquire the only permit + var blockingLease = await limiter.AcquireAsync(1, TestContext.CancellationToken); + _ = blockingLease.IsAcquired.Should().BeTrue(); + + bool actionExecuted = false; + var actionTask = Task.Run( + async () => await limiter.ApplyToAsync( + _ => + { + actionExecuted = true; + + return Task.CompletedTask; + }, + idleTime: TimeSpan.FromMilliseconds(10), + cancellationToken: TestContext.CancellationToken), + TestContext.CancellationToken); + + // wait a bit to ensure the action is waiting + await Task.Delay(50, TestContext.CancellationToken); + _ = actionExecuted.Should().BeFalse(); + + // Act: release the permit + blockingLease.Dispose(); + + // wait for action to complete + await actionTask; + + // Assert + _ = actionExecuted.Should().BeTrue(); + } + + [TestMethod] + public async Task ApplyToAsync_action_respects_permitCount_parameter() + { + // Arrange + using var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions + { + PermitLimit = 5, + QueueLimit = 0 + }); + + int permitCount = 3; + bool canAcquireRemaining = false; + + // Act + await limiter.ApplyToAsync( + async ct => + { + // while inside the action with 3 permits acquired, + // we should be able to acquire the 2 remaining permits + using var remainingLease = await limiter.AcquireAsync(2, ct); + canAcquireRemaining = remainingLease.IsAcquired; + }, + permitCount: permitCount, + cancellationToken: TestContext.CancellationToken); + + // Assert: we should have been able to acquire the remaining 2 permits + _ = canAcquireRemaining.Should().BeTrue(); + } + + [TestMethod] + public async Task ApplyToAsync_action_respects_cancellationToken() + { + // Arrange + using var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions + { + PermitLimit = 1, + QueueLimit = 0 + }); + + // acquire the only permit + using var blockingLease = await limiter.AcquireAsync(1, TestContext.CancellationToken); + + using var cts = new CancellationTokenSource(); + + // Act + var actionTask = Task.Run( + async () => await limiter.ApplyToAsync( + _ => Task.CompletedTask, + idleTime: TimeSpan.FromMilliseconds(10), + cancellationToken: cts.Token), + TestContext.CancellationToken); + + // wait a bit to ensure we're waiting for permits + await Task.Delay(50, TestContext.CancellationToken); + + await cts.CancelAsync(); + + var act = async () => await actionTask; + + // Assert + _ = await act.Should().ThrowAsync(); + } + + [TestMethod] + public async Task ApplyToAsync_request_throws_ArgumentNullException_when_limiter_is_null() + { + // Arrange + RateLimiter limiter = null!; + Func> request = _ => Task.FromResult(42); + + // Act + var act = async () => await limiter.ApplyToAsync(request, cancellationToken: TestContext.CancellationToken); + + // Assert + _ = await act.Should().ThrowAsync(); + } + + [TestMethod] + public async Task ApplyToAsync_request_throws_ArgumentNullException_when_request_is_null() + { + // Arrange + using var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions + { + PermitLimit = 1, + QueueLimit = 0 + }); + + Func> request = null!; + + // Act + var act = async () => await limiter.ApplyToAsync(request, cancellationToken: TestContext.CancellationToken); + + // Assert + _ = await act.Should().ThrowAsync(); + } + + [TestMethod] + public async Task ApplyToAsync_request_executes_request_and_returns_result_when_permits_are_available() + { + // Arrange + using var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions + { + PermitLimit = 10, + QueueLimit = 0 + }); + + int expectedResult = 42; + + // Act + int result = await limiter.ApplyToAsync( + _ => Task.FromResult(expectedResult), + cancellationToken: TestContext.CancellationToken); + + // Assert + _ = result.Should().Be(expectedResult); + } + + [TestMethod] + public async Task ApplyToAsync_request_acquires_and_releases_permit() + { + // Arrange + using var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions + { + PermitLimit = 1, + QueueLimit = 0 + }); + + // Act + _ = await limiter.ApplyToAsync( + _ => Task.FromResult("result"), + cancellationToken: TestContext.CancellationToken); + + // Assert: after execution, permit should be available again + using var lease = await limiter.AcquireAsync(1, TestContext.CancellationToken); + _ = lease.IsAcquired.Should().BeTrue(); + } + + [TestMethod] + public async Task ApplyToAsync_request_releases_permit_even_when_request_throws() + { + // Arrange + using var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions + { + PermitLimit = 1, + QueueLimit = 0 + }); + + // Act + var act = async () => await limiter.ApplyToAsync( + _ => throw new InvalidOperationException("Test exception"), + cancellationToken: TestContext.CancellationToken); + + // Assert + _ = await act.Should().ThrowAsync(); + + // verify permit is available again + using var lease = await limiter.AcquireAsync(1, TestContext.CancellationToken); + _ = lease.IsAcquired.Should().BeTrue(); + } + + [TestMethod] + public async Task ApplyToAsync_request_waits_and_retries_when_permits_not_immediately_available() + { + // Arrange + using var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions + { + PermitLimit = 1, + QueueLimit = 0 + }); + + // acquire the only permit + var blockingLease = await limiter.AcquireAsync(1, TestContext.CancellationToken); + _ = blockingLease.IsAcquired.Should().BeTrue(); + + bool requestExecuted = false; + var requestTask = Task.Run( + async () => await limiter.ApplyToAsync( + _ => + { + requestExecuted = true; + + return Task.FromResult(100); + }, + idleTime: TimeSpan.FromMilliseconds(10), + cancellationToken: TestContext.CancellationToken), + TestContext.CancellationToken); + + // wait a bit to ensure the request is waiting + await Task.Delay(50, TestContext.CancellationToken); + _ = requestExecuted.Should().BeFalse(); + + // Act: release the permit + blockingLease.Dispose(); + + // wait for request to complete + int result = await requestTask; + + // Assert + _ = requestExecuted.Should().BeTrue(); + _ = result.Should().Be(100); + } + + [TestMethod] + public async Task ApplyToAsync_request_respects_permitCount_parameter() + { + // Arrange + using var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions + { + PermitLimit = 5, + QueueLimit = 0 + }); + + int permitCount = 3; + bool canAcquireRemaining = false; + + // Act + string result = await limiter.ApplyToAsync( + async ct => + { + // while inside the request with 3 permits acquired, + // we should be able to acquire the 2 remaining permits + using var remainingLease = await limiter.AcquireAsync(2, ct); + canAcquireRemaining = remainingLease.IsAcquired; + + return "success"; + }, + permitCount: permitCount, + cancellationToken: TestContext.CancellationToken); + + // Assert + _ = result.Should().Be("success"); + _ = canAcquireRemaining.Should().BeTrue(); + } + + [TestMethod] + public async Task ApplyToAsync_request_respects_cancellationToken() + { + // Arrange + using var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions + { + PermitLimit = 1, + QueueLimit = 0 + }); + + // acquire the only permit + using var blockingLease = await limiter.AcquireAsync(1, TestContext.CancellationToken); + + using var cts = new CancellationTokenSource(); + + // Act + var requestTask = Task.Run( + async () => await limiter.ApplyToAsync( + _ => Task.FromResult(42), + idleTime: TimeSpan.FromMilliseconds(10), + cancellationToken: cts.Token), + TestContext.CancellationToken); + + // wait a bit to ensure we're waiting for permits + await Task.Delay(50, TestContext.CancellationToken); + + await cts.CancelAsync(); + + var act = async () => await requestTask; + + // Assert + _ = await act.Should().ThrowAsync(); + } + + [TestMethod] + public async Task ApplyToAsync_action_uses_custom_idleTime() + { + // Arrange + using var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions + { + PermitLimit = 1, + QueueLimit = 0 + }); + + // acquire the only permit + using var blockingLease = await limiter.AcquireAsync(1, TestContext.CancellationToken); + + var customIdleTime = TimeSpan.FromMilliseconds(100); + var stopwatch = System.Diagnostics.Stopwatch.StartNew(); + + var actionTask = Task.Run( + async () => + { + await limiter.ApplyToAsync( + _ => Task.CompletedTask, + idleTime: customIdleTime, + cancellationToken: TestContext.CancellationToken); + }, + TestContext.CancellationToken); + + // wait to ensure multiple retry attempts + await Task.Delay(250, TestContext.CancellationToken); + + blockingLease.Dispose(); + await actionTask; + + stopwatch.Stop(); + + // Assert: should have taken at least 2 idle periods + _ = stopwatch.ElapsedMilliseconds.Should().BeGreaterThanOrEqualTo(200); + } + + [TestMethod] + public async Task ApplyToAsync_request_works_with_complex_return_types() + { + // Arrange + using var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions + { + PermitLimit = 10, + QueueLimit = 0 + }); + + var expectedList = new List { "a", "b", "c" }; + + // Act + List result = await limiter.ApplyToAsync( + _ => Task.FromResult(expectedList), + cancellationToken: TestContext.CancellationToken); + + // Assert + _ = result.Should().BeSameAs(expectedList); + } + + [TestMethod] + public async Task ApplyToAsync_action_uses_custom_timeProvider() + { + // Arrange + using var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions + { + PermitLimit = 1, + QueueLimit = 0 + }); + + // acquire the only permit + using var blockingLease = await limiter.AcquireAsync(1, TestContext.CancellationToken); + + var frozenTime = new DateTimeOffset(2024, 1, 1, 12, 0, 0, TimeSpan.Zero); + var timeProvider = new FrozenTimeProvider(frozenTime); + bool actionExecuted = false; + + var actionTask = Task.Run( + async () => + { + await limiter.ApplyToAsync( + _ => + { + actionExecuted = true; + + return Task.CompletedTask; + }, + idleTime: TimeSpan.FromMilliseconds(100), + timeProvider: timeProvider, + cancellationToken: TestContext.CancellationToken); + }, + TestContext.CancellationToken); + + // wait to ensure the action is waiting + await Task.Delay(50, TestContext.CancellationToken); + + // Act: release the permit + blockingLease.Dispose(); + await actionTask; + + // Assert + _ = actionExecuted.Should().BeTrue(); + } + + [TestMethod] + public async Task ApplyToAsync_request_uses_custom_timeProvider() + { + // Arrange + using var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions + { + PermitLimit = 1, + QueueLimit = 0 + }); + + // acquire the only permit + using var blockingLease = await limiter.AcquireAsync(1, TestContext.CancellationToken); + + var frozenTime = new DateTimeOffset(2024, 1, 1, 12, 0, 0, TimeSpan.Zero); + var timeProvider = new FrozenTimeProvider(frozenTime); + + var requestTask = Task.Run( + async () => await limiter.ApplyToAsync( + _ => Task.FromResult(42), + idleTime: TimeSpan.FromMilliseconds(100), + timeProvider: timeProvider, + cancellationToken: TestContext.CancellationToken), + TestContext.CancellationToken); + + // wait to ensure the request is waiting + await Task.Delay(50, TestContext.CancellationToken); + + // Act: release the permit + blockingLease.Dispose(); + int result = await requestTask; + + // Assert + _ = result.Should().Be(42); + } + + [TestMethod] + public async Task ApplyToAsync_action_uses_System_timeProvider_when_null() + { + // Arrange + using var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions + { + PermitLimit = 10, + QueueLimit = 0 + }); + + bool actionExecuted = false; + + // Act: pass null for timeProvider, should use TimeProvider.System + await limiter.ApplyToAsync( + _ => + { + actionExecuted = true; + + return Task.CompletedTask; + }, + timeProvider: null, + cancellationToken: TestContext.CancellationToken); + + // Assert + _ = actionExecuted.Should().BeTrue(); + } + + [TestMethod] + public async Task ApplyToAsync_request_uses_System_timeProvider_when_null() + { + // Arrange + using var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions + { + PermitLimit = 10, + QueueLimit = 0 + }); + + // Act: pass null for timeProvider, should use TimeProvider.System + int result = await limiter.ApplyToAsync( + _ => Task.FromResult(100), + timeProvider: null, + cancellationToken: TestContext.CancellationToken); + + // Assert + _ = result.Should().Be(100); + } +} From 130e6033955c72879dad710bce7ced4ad6374c07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Luis=20Barreda=20G=C3=BCere=C3=B1a?= Date: Sat, 18 Oct 2025 01:35:58 -0700 Subject: [PATCH 6/6] test: update method names and key assertion syntax Updated method names in `LoggingScopePropertiesBuilderTests` to follow PascalCase naming conventions for consistency. Replaced `ToArray()` with modern syntax `[.. capturedProperties.Keys]` for asserting key order in tests. No functional changes were made to the test logic. --- .../LoggingScopePropertiesBuilderTests.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/DevElf.Logging.Tests/LoggingScopePropertiesBuilderTests.cs b/tests/DevElf.Logging.Tests/LoggingScopePropertiesBuilderTests.cs index 5b7277e..950f658 100644 --- a/tests/DevElf.Logging.Tests/LoggingScopePropertiesBuilderTests.cs +++ b/tests/DevElf.Logging.Tests/LoggingScopePropertiesBuilderTests.cs @@ -197,7 +197,7 @@ public void BeginScope_can_be_called_multiple_times() #region Constructor and Initial Property Tests [TestMethod] - public void builder_includes_initial_property_from_constructor() + public void Builder_includes_initial_property_from_constructor() { // Arrange ILogger logger = Substitute.For(); @@ -217,7 +217,7 @@ public void builder_includes_initial_property_from_constructor() #region Property Order and Type Tests [TestMethod] - public void builder_preserves_property_order() + public void Builder_preserves_property_order() { // Arrange ILogger logger = Substitute.For(); @@ -231,14 +231,14 @@ public void builder_preserves_property_order() .BeginScope(); // Assert - string[] keys = capturedProperties.Keys.ToArray(); + string[] keys = [.. capturedProperties.Keys]; _ = keys[0].Should().Be("First"); _ = keys[1].Should().Be("Second"); _ = keys[2].Should().Be("Third"); } [TestMethod] - public void builder_works_with_various_value_types() + public void Builder_works_with_various_value_types() { // Arrange ILogger logger = Substitute.For();