diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..9602363 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,221 @@ +# Kampute.HttpClient - AI Coding Assistant Instructions + +## Project Overview + +Kampute.HttpClient is a .NET library that enhances the native `HttpClient` for simplified RESTful API communication. It provides a modular, extensible architecture with shared connection pooling, scoped request customization, automatic content deserialization, and built-in retry strategies. + +## Architecture & Design Patterns + +### Core Components +- **`HttpRestClient`**: Main client class wrapping `HttpClient` with enhanced features +- **Extension Packages**: Modular serialization support (`Json`, `Xml`, `DataContract`, `NewtonsoftJson`) +- **Shared HttpClient**: Connection pooling via `SharedHttpClient` for efficient resource management +- **Scoped Collections**: `ScopedCollection` for temporary header/property overrides + +### Key Design Patterns +- **Fluent API**: Extension methods for HTTP verbs (`GetAsync`, `PostAsJsonAsync`, etc.) +- **Event-driven**: `BeforeSendingRequest`/`AfterReceivingResponse` events for interception +- **Strategy Pattern**: `IHttpBackoffProvider` for configurable retry logic +- **Factory Pattern**: `BackoffStrategies` for creating retry policies +- **Decorator Pattern**: `HttpRequestScope` for fluent request configuration + +### Request Flow +1. **Request Creation**: `CreateHttpRequest()` builds `HttpRequestMessage` with headers/properties +2. **Pre-processing**: `BeforeSendingRequest` event allows modification +3. **Dispatch**: `DispatchAsync()` sends via underlying `HttpClient` +4. **Retry Logic**: `DispatchWithRetriesAsync()` handles failures with backoff strategies +5. **Response Processing**: `DeserializeContentAsync()` converts response to .NET objects +6. **Post-processing**: `AfterReceivingResponse` event for inspection/logging + +## Critical Developer Workflows + +### Building & Testing +```bash +# Build solution +dotnet build -c Release + +# Run all tests +dotnet test --verbosity minimal + +# Run specific test project +dotnet test tests/Kampute.HttpClient.Test/ + +# Generate documentation +kampose build +``` + +### Adding New Features +1. **Core Features**: Modify `HttpRestClient.cs` and add tests in corresponding test file +2. **Extensions**: Create new package in `src/Kampute.HttpClient.*` with matching test project +3. **Serialization**: Implement `IHttpContentDeserializer` and add to `ResponseDeserializers` + +### Debugging Common Issues +- **Connection Pooling**: Use `SharedHttpClient` reference counting for proper disposal +- **Header Conflicts**: Scoped headers override defaults; avoid setting headers on underlying `HttpClient` +- **Serialization Failures**: Check `ResponseDeserializers` collection has appropriate deserializer +- **Retry Behavior**: Verify `BackoffStrategy` is set and `ErrorHandlers` are configured + +## Project-Specific Conventions + +### Code Style & Structure +- **Namespaces**: `Kampute.HttpClient` (core), `Kampute.HttpClient.*` (extensions) +- **Naming**: PascalCase for public APIs, consistent with .NET conventions +- **Documentation**: XML comments with ``, ``, and `` sections +- **Nullability**: `Nullable` enabled with proper `?` annotations +- **Async/Await**: Fully asynchronous APIs with `CancellationToken` support + +### Testing Patterns +- **Framework**: NUnit with Moq for mocking +- **Structure**: Test classes mirror source structure (`HttpRestClientTests.cs`) +- **Mocking**: `Mock` for HTTP interactions +- **Helpers**: `TestHelpers` namespace for shared test utilities +- **Coverage**: Comprehensive unit tests for all public APIs + +### Extension Package Pattern +```csharp +// Extension method pattern +public static class HttpRestClientJsonExtensions +{ + public static void AcceptJson(this HttpRestClient client) + { + client.ResponseDeserializers.Add(new JsonContentDeserializer()); + } + + public static Task PostAsJsonAsync(this HttpRestClient client, string uri, object payload) + { + return client.SendAsync(HttpVerb.Post, uri, CreateJsonContent(payload)); + } +} +``` + +### Error Handling +- **Exceptions**: `HttpResponseException` for HTTP errors, `HttpContentException` for deserialization failures +- **Custom Errors**: Implement `IHttpErrorResponse` for structured error responses +- **Retry Logic**: `IHttpErrorHandler` implementations for status-code specific handling +- **Logging**: Use request/response events for comprehensive logging + +### Configuration Management +- **Base Address**: Trailing slash handling in `BaseAddress` setter +- **Headers**: `DefaultRequestHeaders` vs scoped headers precedence +- **Accept Headers**: Auto-generated from `ResponseDeserializers` if not specified +- **Properties**: Request-scoped properties via `HttpRequestMessagePropertyKeys` + +## Integration Points + +### External Dependencies +- **Core**: `System.Net.Http` (native .NET) +- **JSON**: `System.Text.Json` or `Newtonsoft.Json` +- **XML**: `System.Runtime.Serialization` or `System.Xml.Serialization` +- **Testing**: NUnit, Moq, Microsoft.NET.Test.Sdk + +### Cross-Component Communication +- **Events**: `BeforeSendingRequest`/`AfterReceivingResponse` for observability +- **Scopes**: `BeginHeaderScope()`/`BeginPropertyScope()` for request customization +- **Extensions**: Fluent chaining via `HttpRequestScope.WithScope().SetHeader()...PerformAsync()` +- **Handlers**: `ErrorHandlers` collection for pluggable error handling + +## Key Files & Directories + +### Core Implementation +- `src/Kampute.HttpClient/HttpRestClient.cs` - Main client implementation +- `src/Kampute.HttpClient/HttpRestClientExtensions.cs` - HTTP verb extensions +- `src/Kampute.HttpClient/BackoffStrategies.cs` - Retry strategy factories +- `src/Kampute.HttpClient/Utilities/ScopedCollection.cs` - Scoped state management + +### Extension Packages +- `src/Kampute.HttpClient.Json/` - System.Text.Json integration +- `src/Kampute.HttpClient.Xml/` - XML serialization support +- `src/Kampute.HttpClient.DataContract/` - DataContractSerializer integration +- `src/Kampute.HttpClient.NewtonsoftJson/` - Newtonsoft.Json support + +### Testing +- `tests/Kampute.HttpClient.Test/` - Core functionality tests +- `tests/Kampute.HttpClient.Json.Test/` - JSON extension tests +- `TestHelpers/` - Shared testing utilities + +### Build & CI/CD +- `Kampute.HttpClient.sln` - Solution file +- `.github/workflows/main.yml` - GitHub Actions CI/CD +- `kampose.json` - Documentation generation config + +## Common Patterns & Examples + +### Basic Usage +```csharp +using var client = new HttpRestClient(); +client.AcceptJson(); // Add JSON deserializer + +var data = await client.GetAsync("https://api.example.com/data"); +``` + +### Scoped Configuration +```csharp +using var client = new HttpRestClient(); + +var result = await client + .WithScope() + .SetHeader("Authorization", $"Bearer {token}") + .SetProperty("CustomData", context) + .PerformAsync(scoped => scoped.GetAsync("endpoint")); +``` + +### Error Handling & Retry +```csharp +client.BackoffStrategy = BackoffStrategies.Fibonacci(maxAttempts: 5, initialDelay: TimeSpan.FromSeconds(1)); + +client.ErrorHandlers.Add(new HttpError401Handler(async (client, challenges, token) => { + var auth = await client.PostAsFormAsync("auth/refresh", new { refreshToken }); + return new AuthenticationHeaderValue("Bearer", auth.AccessToken); +})); +``` + +### Custom Serialization +```csharp +public class CustomDeserializer : IHttpContentDeserializer +{ + public bool CanDeserialize(string mediaType, Type objectType) => + mediaType == "application/custom" && objectType == typeof(CustomType); + + public Task DeserializeAsync(HttpContent content, Type objectType, CancellationToken token) => + // Custom deserialization logic +} + +client.ResponseDeserializers.Add(new CustomDeserializer()); +``` + +## Quality Assurance + +### Code Quality Checks +- **Build**: `dotnet build -c Release` ensures compilation +- **Tests**: `dotnet test` runs full test suite +- **Documentation**: `kampose build` generates API docs +- **Analysis**: Nullable reference types enabled for null safety + +### Performance Considerations +- **Connection Pooling**: Use `SharedHttpClient` for multiple client instances +- **Async Operations**: All I/O operations are fully asynchronous +- **Memory Management**: Proper `IDisposable` implementation with reference counting +- **Serialization**: Efficient deserialization with content-type matching + +### Security Best Practices +- **Header Injection**: Scoped headers prevent accidental global state changes +- **Authentication**: Built-in support for various auth schemes via error handlers +- **Cancellation**: `CancellationToken` support throughout async APIs +- **Error Handling**: Structured error responses prevent information leakage + +## Development Guidelines +- **SOLID principles**: Prioritize Single Responsibility and Open/Closed principles +- **Simplicity over complexity**: Avoid excessive helper methods and unnecessary abstractions +- **Self-documenting code**: Code should be readable without redundant inline comments +- **Interface pragmatism**: Use interfaces judiciously - avoid "Ravioli" (too many small interfaces) and "Lasagna" (too many layers) +- **Performance & clarity**: Optimize for both execution speed and code understanding +- **Problem-solving approach**: Question existing solutions, propose improvements, document limitations when needed + +## Documentation Guidelines +- Avoid promotional, flowery, or overly embellished language, and use adjectives and adverbs only when strictly necessary. +- Emphasize purpose and usage; do not document implementation details or obvious information. +- Provide meaningful context and call out important behavioral nuances or edge cases. +- Keep content concise and focused by using short sentences and brief paragraphs to convey information clearly. +- Organize content using bullet points, numbered lists, or tables when appropriate, and explain the context or purpose of the list or table in at least one paragraph. +- Numbered lists should be used for steps in a process or sequence only. +- When writing XML documentation comments, use appropriate XML tags for references, language keywords, and for organizing information in lists and tables. Ensure tags are used to clarify context, structure information, and improve readability for consumers of the documentation. diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1111088..ae8ad23 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -7,48 +7,39 @@ on: pull_request: branches: [ master ] -permissions: - contents: write - jobs: build-test-document: runs-on: ubuntu-latest + permissions: + contents: write + steps: - uses: actions/checkout@v4 - - name: Setup .NET 6.0 + - name: Setup .NET 8.0 uses: actions/setup-dotnet@v3 with: - dotnet-version: '6.0.x' + dotnet-version: '8.0.x' + + - name: Install Kampose + run: dotnet tool install --global kampose - - name: Restore dependencies + - name: Restore Dependencies run: dotnet restore - - name: Build + - name: Build Solution run: dotnet build --no-restore -c Release - - name: Test + - name: Test Solution run: dotnet test --no-restore --verbosity minimal - - name: Setup DocFX - run: | - wget https://github.com/dotnet/docfx/releases/download/v2.75.3/docfx-linux-x64-v2.75.3.zip -O docfx.zip - unzip docfx.zip -d docfx - - name: Generate Documentation - run: | - docfx/docfx docfx.json - - - name: Prepare Docs for Deployment - run: | - mv ./docs/README.html ./docs/index.html - cp ICON.png ./docs/ - cp LICENSE ./docs/ + run: kampose build - - name: Deploy to GitHub Pages - uses: peaceiris/actions-gh-pages@v3 + - name: Deploy Documentation to GitHub Pages if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' + uses: peaceiris/actions-gh-pages@v4 with: github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./docs + publish_dir: ./.site diff --git a/.gitignore b/.gitignore index 1e13dab..c1f2556 100644 --- a/.gitignore +++ b/.gitignore @@ -240,14 +240,6 @@ ClientBin/ *.publishsettings orleans.codegen.cs -# Including strong name files can present a security risk -# (https://github.com/github/gitignore/pull/2483#issue-259490424) -#*.snk - -# Since there are multiple workflows, uncomment next line to ignore bower_components -# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) -#bower_components/ - # RIA/Silverlight projects Generated_Code/ @@ -364,4 +356,10 @@ FodyWeavers.xsd # Key files *.pfx -*.snk \ No newline at end of file +*.snk + +# VS Code settings folder +.vscode/ + +# Static website output +.site/ diff --git a/ICON.png b/ICON.png deleted file mode 100644 index 7293eba..0000000 Binary files a/ICON.png and /dev/null differ diff --git a/README.md b/README.md index cac4b75..8ff587c 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,10 @@ -# Kampute.HttpClient - -[![Release](https://img.shields.io/github/v/release/kampute/http-client)](https://github.com/kampute/http-client/releases/latest) -[![Build](https://github.com/kampute/http-client/actions/workflows/main.yml/badge.svg?branch=master)](https://github.com/kampute/http-client/actions/workflows/main.yml) +# Welcome to HttpClient `Kampute.HttpClient` is a .NET library designed to simplify HTTP communication with RESTful APIs by enhancing the native `HttpClient` capabilities. Tailored for developers seeking a potent yet flexible HTTP client for API integration within .NET applications, it combines ease of use with a wide array of functionalities to address the complexities of web service consumption. -[Explore the API documentation](https://kampute.github.io/http-client/api/Kampute.HttpClient.html) for detailed insights. +[Explore the API documentation](https://kampute.github.io/http-client/api/) for detailed insights. ## Key Features @@ -56,20 +53,20 @@ to address the complexities of web service consumption. By default, `Kampute.HttpClient` does not include any content deserializer. To accommodate popular content types, the following extension packages are available: -- **[Kampute.HttpClient.Json](https://www.nuget.org/packages/Kampute.HttpClient.Json)**: +- **[Kampute.HttpClient.Json](https://kampute.github.io/http-client/api/Kampute.HttpClient.Json)**: Utilizes the `System.Text.Json` library for handling JSON content types, offering high-performance serialization and deserialization that integrates tightly with the .NET ecosystem. -- **[Kampute.HttpClient.NewtonsoftJson](https://www.nuget.org/packages/Kampute.HttpClient.NewtonsoftJson)**: +- **[Kampute.HttpClient.NewtonsoftJson](https://kampute.github.io/http-client/api/Kampute.HttpClient.NewtonsoftJson)**: Leverages the `Newtonsoft.Json` library for handling JSON content types, providing extensive customization options and compatibility with a vast number of JSON features and formats. -- **[Kampute.HttpClient.Xml](https://www.nuget.org/packages/Kampute.HttpClient.Xml)**: +- **[Kampute.HttpClient.Xml](https://kampute.github.io/http-client/api/Kampute.HttpClient.Xml)**: Employs the `XmlSerializer` for handling XML content types, enabling straightforward serialization and deserialization of XML into .NET objects using custom class structures. -- **[Kampute.HttpClient.DataContract](https://www.nuget.org/packages/Kampute.HttpClient.DataContract)**: - Utilizes the `DataContractSerializer` for handling XML content types, focusing on serialization and deserialization of .NET objects into XML based on data contract +- **[Kampute.HttpClient.DataContract](https://kampute.github.io/http-client/api/Kampute.HttpClient.DataContract)**: + Utilizes the `DataContractSerializer` for handling XML content types, focusing on serialization and deserialization of .NET objects into XML based on data contract attributes for fine-grained control over the XML output. For scenarios where the provided serialization packages do not meet specific requirements, `Kampute.HttpClient` allows the implementation of custom deserializers. @@ -153,7 +150,7 @@ var csv = await client Similar to headers, you can also scope request properties. This capability is invaluable in scenarios where you need to maintain state or context-specific information temporarily during a series of HTTP operations. Scoped properties work similarly to scoped headers, allowing developers to define temporary data attached to requests that are automatically -cleared once the scope is exited. This feature enhances the adaptability of your HTTP interactions, especially in complex or state-dependent communication scenarios. +cleared once the scope is exited. This feature enhances the adaptability of your HTTP interactions, especially in complex or state-dependent communication scenarios. ### Custom Retry Strategies @@ -168,7 +165,7 @@ using Kampute.HttpClient; using var client = new HttpRestClient(); // Configure the client's retry mechanism. -// The Fibonacci strategy will retry up to 5 times +// The Fibonacci strategy will retry up to 5 times // with an initial delay of 1 second between retries // and delay increases following the Fibonacci sequence for subsequent retries. client.BackoffStrategy = BackoffStrategies.Fibonacci(maxAttempts: 5, initialDelay: TimeSpan.FromSeconds(1)); @@ -187,7 +184,7 @@ using Kampute.HttpClient.ErrorHandlers; // This handler defines the logic to handle unauthorized responses. using var unauthorizedErrorHandler = new HttpError401Handler(async (client, challenges, cancellationToken) => { - // In this example, we're handling the unauthorized error by making a POST request to an + // In this example, we're handling the unauthorized error by making a POST request to an // authentication endpoint to obtain a new authentication token. var auth = await client.PostAsFormAsync("https://api.example.com/auth", [ @@ -251,15 +248,20 @@ await client.PostAsXmlAsync("https://api.example.com/resource", newResource); ## Documentation -Explore the `Kampute.HttpClient` library's [API Documentation](https://kampute.github.io/http-client/api/Kampute.HttpClient.html) for an in-depth understanding of its +Explore the `Kampute.HttpClient` library's [API Documentation](https://kampute.github.io/http-client/api/) for an in-depth understanding of its functionalities. You'll find detailed class references, method signatures, and descriptions of properties to guide your implementation and leverage the library's full potential. ## Contributing -Contributions are welcomed! Please feel free to fork the repository, make changes, and submit pull requests. For major changes or new features, please open an issue -first to discuss what you would like to change. +Contributions welcome! Please follow the existing coding and documentation conventions to maintain consistency across the codebase. + +1. Fork the repository +2. Create a feature branch: `git checkout -b feature-name` +3. Commit changes: `git commit -m 'Add feature'` +4. Push branch: `git push origin feature-name` +5. Open a pull request ## License -`Kampute.HttpClient` is licensed under the terms of the MIT license. See the [LICENSE](LICENSE) file for more details. +Licensed under the [MIT License](LICENSE). diff --git a/docfx.json b/docfx.json deleted file mode 100644 index 2f76eb8..0000000 --- a/docfx.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "metadata": [ - { - "src": [ - { - "files": [ "src/**/*.csproj" ], - "exclude": [ "**/obj/**", "**/bin/**" ], - "properties": { - "TargetFrameworks": "netstandard2.0;netstandard2.1", - "OutputPaths": [ - "bin/Release/netstandard2.0", - "bin/Release/netstandard2.1" - ] - }, - "codeProjectProperties": { - "ProjectReferences": [ - { - "ProjectPath": "**/*.csproj" - } - ] - } - } - ], - "dest": "api" - } - ], - "build": { - "content": [ - { - "files": "**/*.yml" - }, - { - "files": "README.md" - } - ], - "globalMetadata": { - "_appName": "Kampute.HttpClient .NET Library", - "_appTitle": "Kampute.HttpClient .NET Library", - "_appFooter": "© 2024 Kampute", - "_appFaviconPath": "ICON.png", - "_appLogoPath": "ICON.png", - "_disableContribution": true, - "_disableNavbar": true, - "_disableNewTab": true - }, - "sitemap": { - "baseUrl": "https://kampute.github.io/http-client" - }, - "template": [ "default", "modern" ], - "dest": "docs" - } -} diff --git a/kampose.json b/kampose.json new file mode 100644 index 0000000..57f268e --- /dev/null +++ b/kampose.json @@ -0,0 +1,40 @@ +{ + "convention": "docfx", + "outputDirectory": ".site", + "audit": { + "options": [ + "recommended" + ], + "stopOnIssues": true + }, + "assemblies": [ + "src/**/bin/Release/netstandard2.1/*.dll" + ], + "assets": [ + { + "source": [ + "LICENSE", + "logo-dark.png", + "logo-light.png" + ] + } + ], + "references": [ + { + "namespaces": [ + "Newtonsoft.Json.*" + ], + "strategy": "onlineSearch", + "url": "https://www.phind.com/search/" + } + ], + "theme": "classic", + "themeSettings": { + "projectName": "Kampute.HttpClient", + "projectSlogan": "A lightweight .NET library that simplifies RESTful API communication.", + "projectLogoLightUri": "logo-dark.png", + "projectLogoDarkUri": "logo-light.png", + "faviconUri": "logo-dark.png", + "pageFooter": "- Copyright © {{now 'yyyy'}} [Kampute](https://kampute.com/)\n- Site built with [Kampose](https://kampute.github.io/kampose/)." + } +} diff --git a/logo-dark.png b/logo-dark.png new file mode 100644 index 0000000..48ed448 Binary files /dev/null and b/logo-dark.png differ diff --git a/logo-light.png b/logo-light.png new file mode 100644 index 0000000..a4bf3e9 Binary files /dev/null and b/logo-light.png differ diff --git a/src/Kampute.HttpClient.DataContract/Kampute.HttpClient.DataContract.csproj b/src/Kampute.HttpClient.DataContract/Kampute.HttpClient.DataContract.csproj index f94f6e0..49f2bf2 100644 --- a/src/Kampute.HttpClient.DataContract/Kampute.HttpClient.DataContract.csproj +++ b/src/Kampute.HttpClient.DataContract/Kampute.HttpClient.DataContract.csproj @@ -5,7 +5,7 @@ Kampute.HttpClient.DataContract This package is an extension package for Kampute.HttpClient, enhancing it to manage application/xml content types, using DataContractSerializer for serialization and deserialization of XML responses and payloads. Kambiz Khojasteh - 2.3.1 + 2.3.2 Kampute Copyright (c) 2024 Kampute latest @@ -13,7 +13,7 @@ true snupkg true - true + false Kampute.HttpClient.DataContract http http-client restful rest-client rest-api web-api xml ICON.png diff --git a/src/Kampute.HttpClient.DataContract/NamespaceDoc.cs b/src/Kampute.HttpClient.DataContract/NamespaceDoc.cs new file mode 100644 index 0000000..af65811 --- /dev/null +++ b/src/Kampute.HttpClient.DataContract/NamespaceDoc.cs @@ -0,0 +1,13 @@ +// Copyright (C) 2024 Kampute +// +// This file is part of the Kampute.HttpClient package and is released under the terms of the MIT license. +// See the LICENSE file in the project root for the full license text. + +namespace Kampute.HttpClient.DataContract +{ + /// + /// This namespace provides support for DataContract serialization in HTTP requests and responses, + /// specifically for handling application/xml content types using the DataContractSerializer. + /// + internal static class NamespaceDoc { } +} diff --git a/src/Kampute.HttpClient.DataContract/XmlContent.cs b/src/Kampute.HttpClient.DataContract/XmlContent.cs index 211f8fc..d0be6e5 100644 --- a/src/Kampute.HttpClient.DataContract/XmlContent.cs +++ b/src/Kampute.HttpClient.DataContract/XmlContent.cs @@ -68,7 +68,12 @@ public XmlContent(object content, Encoding encoding) /// public DataContractSerializerSettings? Settings { get; set; } - /// + /// + /// Serializes the content to a stream asynchronously. + /// + /// The target stream. + /// The transport context. + /// A task that represents the asynchronous operation. protected override Task SerializeToStreamAsync(Stream stream, TransportContext context) { using var streamWriter = new StreamWriter(stream, _encoding, 4096, true); @@ -84,7 +89,11 @@ protected override Task SerializeToStreamAsync(Stream stream, TransportContext c return Task.CompletedTask; } - /// + /// + /// Attempts to compute the length of the content. + /// + /// When this method returns, contains the length of the content in bytes. + /// if the length could be computed; otherwise, . protected override bool TryComputeLength(out long length) { length = -1; diff --git a/src/Kampute.HttpClient.Json/JsonContent.cs b/src/Kampute.HttpClient.Json/JsonContent.cs index 74d264c..8dac131 100644 --- a/src/Kampute.HttpClient.Json/JsonContent.cs +++ b/src/Kampute.HttpClient.Json/JsonContent.cs @@ -44,13 +44,22 @@ public JsonContent(object content) /// public JsonSerializerOptions? Options { get; set; } - /// + /// + /// Serializes the content to a stream asynchronously. + /// + /// The target stream. + /// The transport context. + /// A task that represents the asynchronous operation. protected override Task SerializeToStreamAsync(Stream stream, TransportContext context) { return JsonSerializer.SerializeAsync(stream, _content, Options); } - /// + /// + /// Attempts to compute the length of the content. + /// + /// When this method returns, contains the length of the content in bytes. + /// if the length could be computed; otherwise, . protected override bool TryComputeLength(out long length) { length = -1; diff --git a/src/Kampute.HttpClient.Json/Kampute.HttpClient.Json.csproj b/src/Kampute.HttpClient.Json/Kampute.HttpClient.Json.csproj index bfb5fea..6806861 100644 --- a/src/Kampute.HttpClient.Json/Kampute.HttpClient.Json.csproj +++ b/src/Kampute.HttpClient.Json/Kampute.HttpClient.Json.csproj @@ -5,7 +5,7 @@ Kampute.HttpClient.Json This package is an extension package for Kampute.HttpClient, enhancing it to manage application/json content types, using System.Text.Json library for serialization and deserialization of JSON responses and payloads. Kambiz Khojasteh - 2.3.1 + 2.3.2 Kampute Copyright (c) 2024 Kampute latest @@ -13,7 +13,7 @@ true snupkg true - true + false Kampute.HttpClient.Json http http-client restful rest-client rest-api web-api json ICON.png @@ -36,7 +36,7 @@ - + diff --git a/src/Kampute.HttpClient.Json/NamespaceDoc.cs b/src/Kampute.HttpClient.Json/NamespaceDoc.cs new file mode 100644 index 0000000..084c71f --- /dev/null +++ b/src/Kampute.HttpClient.Json/NamespaceDoc.cs @@ -0,0 +1,13 @@ +// Copyright (C) 2024 Kampute +// +// This file is part of the Kampute.HttpClient package and is released under the terms of the MIT license. +// See the LICENSE file in the project root for the full license text. + +namespace Kampute.HttpClient.Json +{ + /// + /// This namespace provides support for JSON serialization in HTTP requests and responses, + /// specifically for handling application/json content types using System.Text.Json. + /// + internal static class NamespaceDoc { } +} diff --git a/src/Kampute.HttpClient.NewtonsoftJson/JsonContent.cs b/src/Kampute.HttpClient.NewtonsoftJson/JsonContent.cs index d725c5c..1fbfb6d 100644 --- a/src/Kampute.HttpClient.NewtonsoftJson/JsonContent.cs +++ b/src/Kampute.HttpClient.NewtonsoftJson/JsonContent.cs @@ -46,7 +46,12 @@ public JsonContent(object content) /// public JsonSerializerSettings? Settings { get; set; } - /// + /// + /// Serializes the content to a stream asynchronously. + /// + /// The target stream. + /// The transport context. + /// A task that represents the asynchronous operation. protected override Task SerializeToStreamAsync(Stream stream, TransportContext context) { using var streamWriter = new StreamWriter(stream, utf8WithoutMarker, 4096, true); @@ -56,7 +61,11 @@ protected override Task SerializeToStreamAsync(Stream stream, TransportContext c return Task.CompletedTask; } - /// + /// + /// Attempts to compute the length of the content. + /// + /// When this method returns, contains the length of the content in bytes. + /// if the length could be computed; otherwise, . protected override bool TryComputeLength(out long length) { length = -1; diff --git a/src/Kampute.HttpClient.NewtonsoftJson/Kampute.HttpClient.NewtonsoftJson.csproj b/src/Kampute.HttpClient.NewtonsoftJson/Kampute.HttpClient.NewtonsoftJson.csproj index dd8c800..240db10 100644 --- a/src/Kampute.HttpClient.NewtonsoftJson/Kampute.HttpClient.NewtonsoftJson.csproj +++ b/src/Kampute.HttpClient.NewtonsoftJson/Kampute.HttpClient.NewtonsoftJson.csproj @@ -5,7 +5,7 @@ Kampute.HttpClient.NewtonsoftJson This package is an extension package for Kampute.HttpClient, enhancing it to manage application/json content types, using Newtonsoft.Json library for serialization and deserialization of JSON responses and payloads. Kambiz Khojasteh - 2.3.1 + 2.3.2 Kampute Copyright (c) 2024 Kampute latest @@ -13,7 +13,7 @@ true snupkg true - true + false Kampute.HttpClient.NewtonsoftJson http http-client restful rest-client rest-api web-api json ICON.png diff --git a/src/Kampute.HttpClient.NewtonsoftJson/NamespaceDoc.cs b/src/Kampute.HttpClient.NewtonsoftJson/NamespaceDoc.cs new file mode 100644 index 0000000..6af8af3 --- /dev/null +++ b/src/Kampute.HttpClient.NewtonsoftJson/NamespaceDoc.cs @@ -0,0 +1,13 @@ +// Copyright (C) 2024 Kampute +// +// This file is part of the Kampute.HttpClient package and is released under the terms of the MIT license. +// See the LICENSE file in the project root for the full license text. + +namespace Kampute.HttpClient.NewtonsoftJson +{ + /// + /// This namespace provides support for JSON serialization in HTTP requests and responses, + /// specifically for handling application/json content types using Newtonsoft.Json. + /// + internal static class NamespaceDoc { } +} diff --git a/src/Kampute.HttpClient.Xml/Kampute.HttpClient.Xml.csproj b/src/Kampute.HttpClient.Xml/Kampute.HttpClient.Xml.csproj index 522c3df..30949cc 100644 --- a/src/Kampute.HttpClient.Xml/Kampute.HttpClient.Xml.csproj +++ b/src/Kampute.HttpClient.Xml/Kampute.HttpClient.Xml.csproj @@ -5,7 +5,7 @@ Kampute.HttpClient.Xml This package is an extension package for Kampute.HttpClient, enhancing it to manage application/xml content types, using XmlSerializer for serialization and deserialization of XML responses and payloads. Kambiz Khojasteh - 2.3.1 + 2.3.2 Kampute Copyright (c) 2024 Kampute latest @@ -13,13 +13,13 @@ true snupkg true - true + false Kampute.HttpClient.Xml http http-client restful rest-client rest-api web-api xml ICON.png README.md LICENSE - For detailed release notes, please visit https://github.com/kampute/http-client/releases + For detailed release notes, please visit https://github.com/kampute/http-client/releases https://kampute.github.io/http-client/ https://github.com/kampute/http-client.git git diff --git a/src/Kampute.HttpClient.Xml/NamespaceDoc.cs b/src/Kampute.HttpClient.Xml/NamespaceDoc.cs new file mode 100644 index 0000000..e04ff5e --- /dev/null +++ b/src/Kampute.HttpClient.Xml/NamespaceDoc.cs @@ -0,0 +1,13 @@ +// Copyright (C) 2024 Kampute +// +// This file is part of the Kampute.HttpClient package and is released under the terms of the MIT license. +// See the LICENSE file in the project root for the full license text. + +namespace Kampute.HttpClient.Xml +{ + /// + /// This namespace provides support for XML serialization in HTTP requests and responses, + /// specifically for handling application/xml content types using the XmlSerializer. + /// + internal static class NamespaceDoc { } +} diff --git a/src/Kampute.HttpClient.Xml/XmlContent.cs b/src/Kampute.HttpClient.Xml/XmlContent.cs index b836637..be8ec7a 100644 --- a/src/Kampute.HttpClient.Xml/XmlContent.cs +++ b/src/Kampute.HttpClient.Xml/XmlContent.cs @@ -60,7 +60,12 @@ public XmlContent(object content, Encoding encoding) /// public Encoding Encoding => _encoding; - /// + /// + /// Serializes the content to a stream asynchronously. + /// + /// The target stream. + /// The transport context. + /// A task that represents the asynchronous operation. protected override Task SerializeToStreamAsync(Stream stream, TransportContext context) { using var streamWriter = new StreamWriter(stream, _encoding, 4096, true); @@ -76,7 +81,11 @@ protected override Task SerializeToStreamAsync(Stream stream, TransportContext c return Task.CompletedTask; } - /// + /// + /// Attempts to compute the length of the content. + /// + /// When this method returns, contains the length of the content in bytes. + /// if the length could be computed; otherwise, . protected override bool TryComputeLength(out long length) { length = -1; diff --git a/src/Kampute.HttpClient/BackoffStrategies.cs b/src/Kampute.HttpClient/BackoffStrategies.cs index 8de22ec..e57fdf4 100644 --- a/src/Kampute.HttpClient/BackoffStrategies.cs +++ b/src/Kampute.HttpClient/BackoffStrategies.cs @@ -47,8 +47,8 @@ namespace Kampute.HttpClient /// /// /// - /// The Dynamic strategy stands apart, as its delay can vary based on the context of the failure. It tailors retry attempts to specific conditions, such - /// as error type or system load, offering the flexibility to adapt retry logic for optimal outcomes. This approach is most useful in complex systems where a + /// The Dynamic strategy stands apart, as its delay can vary based on the context of the failure. It tailors retry attempts to specific conditions, such + /// as error type or system load, offering the flexibility to adapt retry logic for optimal outcomes. This approach is most useful in complex systems where a /// static retry strategy may not adequately address the nuances of different failure scenarios. /// /// @@ -85,7 +85,7 @@ public static IHttpBackoffProvider Once(TimeSpan delay) /// The date and time after which the single retry attempt will be made. /// An that defines a retry strategy of a single attempt after a specified date and time. /// - /// This strategy schedules a single retry attempt for a specified future point in time, ensuring operations are retried when certain + /// This strategy schedules a single retry attempt for a specified future point in time, ensuring operations are retried when certain /// conditions are likely met. If the specified time has already passed, it immediately schedules the retry attempt. /// public static IHttpBackoffProvider Once(DateTimeOffset after) @@ -114,6 +114,7 @@ public static IHttpBackoffProvider Uniform(uint maxAttempts, TimeSpan delay) /// /// The maximum time to spend retrying. /// The constant delay between each retry attempt. + /// An that defines a retry strategy of multiple attempts with a constant delay between each attempt, up to a specified timeout. /// /// This strategy performs multiple retry attempts with a constant delay between each attempt, up to a specified timeout. It is ideal for cases needing /// multiple attempts with predictable delays, but with a maximum time limit for retrying. @@ -294,7 +295,7 @@ public static IHttpBackoffProvider Fibonacci(TimeSpan timeout, TimeSpan initialD /// An instance of . /// Thrown if is . /// - /// This strategy offers the highest flexibility by dynamically scheduling retries based on the specific context of a failure. It adapts to the nature of + /// This strategy offers the highest flexibility by dynamically scheduling retries based on the specific context of a failure. It adapts to the nature of /// encountered errors, making it ideal for complex systems with varied types of transient failures that cannot be effectively handled by a static retry strategy. /// public static IHttpBackoffProvider Dynamic(Func strategyFactory) @@ -309,7 +310,7 @@ public static IHttpBackoffProvider Dynamic(FuncAn instance of . /// Thrown if is . /// - /// This strategy offers the highest flexibility by dynamically scheduling retries based on the specific context of a failure. It adapts to the nature of + /// This strategy offers the highest flexibility by dynamically scheduling retries based on the specific context of a failure. It adapts to the nature of /// encountered errors, making it ideal for complex systems with varied types of transient failures that cannot be effectively handled by a static retry strategy. /// public static IHttpBackoffProvider Dynamic(Func schedulerFactory) diff --git a/src/Kampute.HttpClient/Content/Abstracts/HttpContentDecorator.cs b/src/Kampute.HttpClient/Content/Abstracts/HttpContentDecorator.cs index 69d301a..0adfa7b 100644 --- a/src/Kampute.HttpClient/Content/Abstracts/HttpContentDecorator.cs +++ b/src/Kampute.HttpClient/Content/Abstracts/HttpContentDecorator.cs @@ -4,7 +4,7 @@ using System.Net.Http; /// - /// Serves as a base class for decorating instances. + /// Serves as a base class for decorating instances. /// /// /// This class provides common functionality such as copying headers from the original content and managing the lifecycle of the wrapped content. @@ -26,6 +26,7 @@ protected HttpContentDecorator(HttpContent content) /// /// Gets the original HTTP content that this instance decorates. /// + /// The original instance. protected internal HttpContent OriginalContent { get; } /// diff --git a/src/Kampute.HttpClient/Content/Abstracts/NamespaceDoc.cs b/src/Kampute.HttpClient/Content/Abstracts/NamespaceDoc.cs new file mode 100644 index 0000000..339a989 --- /dev/null +++ b/src/Kampute.HttpClient/Content/Abstracts/NamespaceDoc.cs @@ -0,0 +1,13 @@ +// Copyright (C) 2024 Kampute +// +// This file is part of the Kampute.HttpClient package and is released under the terms of the MIT license. +// See the LICENSE file in the project root for the full license text. + +namespace Kampute.HttpClient.Content.Abstracts +{ + /// + /// This namespace contains abstract classes for HTTP content + /// deserialization and decoration. + /// + internal static class NamespaceDoc { } +} diff --git a/src/Kampute.HttpClient/Content/Compression/Abstracts/NamespaceDoc.cs b/src/Kampute.HttpClient/Content/Compression/Abstracts/NamespaceDoc.cs new file mode 100644 index 0000000..97f16df --- /dev/null +++ b/src/Kampute.HttpClient/Content/Compression/Abstracts/NamespaceDoc.cs @@ -0,0 +1,12 @@ +// Copyright (C) 2024 Kampute +// +// This file is part of the Kampute.HttpClient package and is released under the terms of the MIT license. +// See the LICENSE file in the project root for the full license text. + +namespace Kampute.HttpClient.Content.Compression.Abstracts +{ + /// + /// This namespace contains abstract base classes for compressed content. + /// + internal static class NamespaceDoc { } +} diff --git a/src/Kampute.HttpClient/Content/Compression/NamespaceDoc.cs b/src/Kampute.HttpClient/Content/Compression/NamespaceDoc.cs new file mode 100644 index 0000000..8eff1fd --- /dev/null +++ b/src/Kampute.HttpClient/Content/Compression/NamespaceDoc.cs @@ -0,0 +1,12 @@ +// Copyright (C) 2024 Kampute +// +// This file is part of the Kampute.HttpClient package and is released under the terms of the MIT license. +// See the LICENSE file in the project root for the full license text. + +namespace Kampute.HttpClient.Content.Compression +{ + /// + /// This namespace provides classes for compressing HTTP content. + /// + internal static class NamespaceDoc { } +} diff --git a/src/Kampute.HttpClient/Content/EmptyContent.cs b/src/Kampute.HttpClient/Content/EmptyContent.cs index 809559f..05a14b8 100644 --- a/src/Kampute.HttpClient/Content/EmptyContent.cs +++ b/src/Kampute.HttpClient/Content/EmptyContent.cs @@ -14,13 +14,22 @@ /// public sealed class EmptyContent : HttpContent { - /// + /// + /// Serializes the content to a stream asynchronously. + /// + /// The target stream to which the content should be written. + /// The transport context. + /// A task that represents the asynchronous operation. protected override Task SerializeToStreamAsync(Stream stream, TransportContext context) { return Task.CompletedTask; } - /// + /// + /// Attempts to compute the length of the content. + /// + /// When this method returns, contains the length of the content in bytes. + /// if the length could be computed; otherwise, . protected override bool TryComputeLength(out long length) { length = 0; diff --git a/src/Kampute.HttpClient/Content/NamespaceDoc.cs b/src/Kampute.HttpClient/Content/NamespaceDoc.cs new file mode 100644 index 0000000..f3c416d --- /dev/null +++ b/src/Kampute.HttpClient/Content/NamespaceDoc.cs @@ -0,0 +1,12 @@ +// Copyright (C) 2024 Kampute +// +// This file is part of the Kampute.HttpClient package and is released under the terms of the MIT license. +// See the LICENSE file in the project root for the full license text. + +namespace Kampute.HttpClient.Content +{ + /// + /// This namespace contains classes for handling HTTP content. + /// + internal static class NamespaceDoc { } +} diff --git a/src/Kampute.HttpClient/ErrorHandlers/HttpError429Handler.cs b/src/Kampute.HttpClient/ErrorHandlers/HttpError429Handler.cs index 34da3db..b0ae86c 100644 --- a/src/Kampute.HttpClient/ErrorHandlers/HttpError429Handler.cs +++ b/src/Kampute.HttpClient/ErrorHandlers/HttpError429Handler.cs @@ -12,13 +12,13 @@ namespace Kampute.HttpClient.ErrorHandlers using System.Threading.Tasks; /// - /// Handles '429 Too Many Requests' HTTP responses by attempting to back off and retry the request according to a specified or + /// Handles '429 Too Many Requests' HTTP responses by attempting to back off and retry the request according to a specified or /// default backoff strategy. /// /// - /// This handler provides a mechanism to respond to HTTP 429 errors by retrying the request after a delay. The delay duration and - /// retry logic can be customized through the delegate. If the delegate is not provided, or does not - /// specify a strategy, the handler will look for a rate limit reset header in the response. If the header is present, its value is + /// This handler provides a mechanism to respond to HTTP 429 errors by retrying the request after a delay. The delay duration and + /// retry logic can be customized through the delegate. If the delegate is not provided, or does not + /// specify a strategy, the handler will look for a rate limit reset header in the response. If the header is present, its value is /// used to determine the backoff duration. If the header is not present, no retries will be attempted. /// /// @@ -27,9 +27,13 @@ public class HttpError429Handler : IHttpErrorHandler /// /// A delegate that allows customization of the backoff strategy when a 429 Too Many Requests' response is received. /// + /// + /// A function that takes an and an optional representing + /// the rate limit reset time, and returns an to define the backoff strategy. + /// /// /// - /// If this delegate is set and returns an , the returned strategy is used for the retry operation. + /// If this delegate is set and returns an , the returned strategy is used for the retry operation. /// If it is not set, or returns , the handler will defer to the Retry-After header in the response. /// /// @@ -45,7 +49,7 @@ public class HttpError429Handler : IHttpErrorHandler /// /// resetTime /// - /// Indicates the time when the rate limit will be lifted as a value. If the server specifies + /// Indicates the time when the rate limit will be lifted as a value. If the server specifies /// a reset time via response headers, this parameter provides that time, allowing the client to know when to resume requests. /// If the server does not specify a reset time, the value will be . /// @@ -77,8 +81,8 @@ public bool CanHandle(HttpStatusCode statusCode) => /// An that schedules the retry attempts. /// Thrown if is . /// - /// This method first attempts to use the delegate to obtain a retry strategy. If the delegate is not - /// provided or returns , and a rate limit reset header is present, the value of this header is used to create a retry delay. + /// This method first attempts to use the delegate to obtain a retry strategy. If the delegate is not + /// provided or returns , and a rate limit reset header is present, the value of this header is used to create a retry delay. /// If neither condition is met, no retries will be attempted. /// protected virtual IRetryScheduler? CreateScheduler(HttpResponseErrorContext ctx) diff --git a/src/Kampute.HttpClient/ErrorHandlers/HttpError503Handler.cs b/src/Kampute.HttpClient/ErrorHandlers/HttpError503Handler.cs index dbc0a2b..4c1ae5e 100644 --- a/src/Kampute.HttpClient/ErrorHandlers/HttpError503Handler.cs +++ b/src/Kampute.HttpClient/ErrorHandlers/HttpError503Handler.cs @@ -12,14 +12,14 @@ namespace Kampute.HttpClient.ErrorHandlers using System.Threading.Tasks; /// - /// Handles '503 Service Unavailable' HTTP responses by attempting to back off and retry the request according to a specified or + /// Handles '503 Service Unavailable' HTTP responses by attempting to back off and retry the request according to a specified or /// default backoff strategy. /// /// - /// This handler provides a mechanism to respond to HTTP 503 errors by retrying the request after a delay. The delay duration and - /// retry logic can be customized through the delegate. If the delegate is not provided, or does not - /// specify a strategy, the handler will look for a Retry-After header in the response. If the Retry-After header is - /// present, its value is used to determine the backoff duration. If the header is not present, the default backoff strategy of the + /// This handler provides a mechanism to respond to HTTP 503 errors by retrying the request after a delay. The delay duration and + /// retry logic can be customized through the delegate. If the delegate is not provided, or does not + /// specify a strategy, the handler will look for a Retry-After header in the response. If the Retry-After header is + /// present, its value is used to determine the backoff duration. If the header is not present, the default backoff strategy of the /// is used. /// /// @@ -29,10 +29,15 @@ public class HttpError503Handler : IHttpErrorHandler /// /// A delegate that allows customization of the backoff strategy when a '503 Service Unavailable' response is received. /// + /// + /// A function that takes an and an optional representing + /// the suggested retry time from the Retry-After header, and returns an to be used + /// for the retry operation. + /// /// /// - /// If this delegate is set and returns an , the returned strategy is used for the retry operation. - /// If it is not set, or returns , the handler will defer to the Retry-After header in the response or the + /// If this delegate is set and returns an , the returned strategy is used for the retry operation. + /// If it is not set, or returns , the handler will defer to the Retry-After header in the response or the /// client's default backoff strategy. /// /// @@ -75,8 +80,8 @@ public class HttpError503Handler : IHttpErrorHandler /// An that schedules the retry attempts. /// Thrown if is . /// - /// This method first attempts to use the delegate to obtain a retry strategy. If the delegate is not - /// provided or returns , and a Retry-After header is present, the value of this header is used to create a retry + /// This method first attempts to use the delegate to obtain a retry strategy. If the delegate is not + /// provided or returns , and a Retry-After header is present, the value of this header is used to create a retry /// delay. If neither condition is met, the client's default backoff strategy is utilized. /// protected virtual IRetryScheduler? CreateScheduler(HttpResponseErrorContext ctx) diff --git a/src/Kampute.HttpClient/ErrorHandlers/NamespaceDoc.cs b/src/Kampute.HttpClient/ErrorHandlers/NamespaceDoc.cs new file mode 100644 index 0000000..5c8f3f2 --- /dev/null +++ b/src/Kampute.HttpClient/ErrorHandlers/NamespaceDoc.cs @@ -0,0 +1,12 @@ +// Copyright (C) 2024 Kampute +// +// This file is part of the Kampute.HttpClient package and is released under the terms of the MIT license. +// See the LICENSE file in the project root for the full license text. + +namespace Kampute.HttpClient.ErrorHandlers +{ + /// + /// This namespace contains classes for handling specific HTTP error responses. + /// + internal static class NamespaceDoc { } +} diff --git a/src/Kampute.HttpClient/Interfaces/NamespaceDoc.cs b/src/Kampute.HttpClient/Interfaces/NamespaceDoc.cs new file mode 100644 index 0000000..eb400b5 --- /dev/null +++ b/src/Kampute.HttpClient/Interfaces/NamespaceDoc.cs @@ -0,0 +1,12 @@ +// Copyright (C) 2024 Kampute +// +// This file is part of the Kampute.HttpClient package and is released under the terms of the MIT license. +// See the LICENSE file in the project root for the full license text. + +namespace Kampute.HttpClient.Interfaces +{ + /// + /// This namespace defines interfaces used throughout the library. + /// + internal static class NamespaceDoc { } +} diff --git a/src/Kampute.HttpClient/Kampute.HttpClient.csproj b/src/Kampute.HttpClient/Kampute.HttpClient.csproj index 6d63377..8f3bd6e 100644 --- a/src/Kampute.HttpClient/Kampute.HttpClient.csproj +++ b/src/Kampute.HttpClient/Kampute.HttpClient.csproj @@ -5,7 +5,7 @@ Kampute.HttpClient Kampute.HttpClient is a versatile and lightweight .NET library that simplifies RESTful API communication. Its core HttpRestClient class provides a streamlined approach to HTTP interactions, offering advanced features such as flexible serialization/deserialization, robust error handling, configurable backoff strategies, and detailed request-response processing. Striking a balance between simplicity and extensibility, Kampute.HttpClient empowers developers with a powerful yet easy-to-use client for seamless API integration across a wide range of .NET applications. Kambiz Khojasteh - 2.3.1 + 2.3.2 Kampute Copyright (c) 2024 Kampute latest @@ -13,7 +13,7 @@ true snupkg true - true + false true Kampute.HttpClient http http-client restful rest-client rest-api web-api diff --git a/src/Kampute.HttpClient/NamespaceDoc.cs b/src/Kampute.HttpClient/NamespaceDoc.cs new file mode 100644 index 0000000..94d260d --- /dev/null +++ b/src/Kampute.HttpClient/NamespaceDoc.cs @@ -0,0 +1,12 @@ +// Copyright (C) 2024 Kampute +// +// This file is part of the Kampute.HttpClient package and is released under the terms of the MIT license. +// See the LICENSE file in the project root for the full license text. + +namespace Kampute.HttpClient +{ + /// + /// This namespace contains classes and methods for making HTTP requests and handling responses. + /// + internal static class NamespaceDoc { } +} diff --git a/src/Kampute.HttpClient/RetryManagement/BackoffStrategy.cs b/src/Kampute.HttpClient/RetryManagement/BackoffStrategy.cs index fb67d44..864d0be 100644 --- a/src/Kampute.HttpClient/RetryManagement/BackoffStrategy.cs +++ b/src/Kampute.HttpClient/RetryManagement/BackoffStrategy.cs @@ -32,6 +32,7 @@ public BackoffStrategy(IRetryStrategy strategy) /// /// Gets the retry strategy associated with this scheduler factory. /// + /// The used by schedulers created by this factory. public virtual IRetryStrategy Strategy { get; } /// diff --git a/src/Kampute.HttpClient/RetryManagement/NamespaceDoc.cs b/src/Kampute.HttpClient/RetryManagement/NamespaceDoc.cs new file mode 100644 index 0000000..00a547d --- /dev/null +++ b/src/Kampute.HttpClient/RetryManagement/NamespaceDoc.cs @@ -0,0 +1,13 @@ +// Copyright (C) 2024 Kampute +// +// This file is part of the Kampute.HttpClient package and is released under the terms of the MIT license. +// See the LICENSE file in the project root for the full license text. + +namespace Kampute.HttpClient.RetryManagement +{ + /// + /// This namespace provides classes and interfaces for managing retry + /// logic and backoff strategies in HTTP requests. + /// + internal static class NamespaceDoc { } +} diff --git a/src/Kampute.HttpClient/RetryManagement/RetryScheduler.cs b/src/Kampute.HttpClient/RetryManagement/RetryScheduler.cs index 5f797d5..b0a4ae8 100644 --- a/src/Kampute.HttpClient/RetryManagement/RetryScheduler.cs +++ b/src/Kampute.HttpClient/RetryManagement/RetryScheduler.cs @@ -32,16 +32,19 @@ public RetryScheduler(IRetryStrategy strategy) /// /// Gets the retry strategy associated with this scheduler. /// + /// The instance used by this scheduler. public virtual IRetryStrategy Strategy { get; } /// /// Gets the number of retry attempts that have been made. /// + /// The number of retry attempts. public virtual uint Attempts => _attempts; /// /// Gets the total elapsed time since the retry attempts were started. /// + /// The elapsed time as a . public virtual TimeSpan Elapsed => _timer.Elapsed; /// @@ -78,7 +81,7 @@ public virtual void Reset() /// Prepares the internal state for the next retry attempt. /// /// - /// This method is called immediately after a retry attempt is determined to be necessary and before the delay for the next attempt begins. + /// This method is called immediately after a retry attempt is determined to be necessary and before the delay for the next attempt begins. /// It allows for updating the internal state or performing any preparations required before the next attempt. /// protected virtual void ReadyNextAttempt() diff --git a/src/Kampute.HttpClient/RetryManagement/Strategies/Modifiers/NamespaceDoc.cs b/src/Kampute.HttpClient/RetryManagement/Strategies/Modifiers/NamespaceDoc.cs new file mode 100644 index 0000000..fa8289b --- /dev/null +++ b/src/Kampute.HttpClient/RetryManagement/Strategies/Modifiers/NamespaceDoc.cs @@ -0,0 +1,12 @@ +// Copyright (C) 2024 Kampute +// +// This file is part of the Kampute.HttpClient package and is released under the terms of the MIT license. +// See the LICENSE file in the project root for the full license text. + +namespace Kampute.HttpClient.RetryManagement.Strategies.Modifiers +{ + /// + /// This namespace provides modifiers that can be applied to retry strategies to alter their behavior. + /// + internal static class NamespaceDoc { } +} diff --git a/src/Kampute.HttpClient/RetryManagement/Strategies/NamespaceDoc.cs b/src/Kampute.HttpClient/RetryManagement/Strategies/NamespaceDoc.cs new file mode 100644 index 0000000..afee57f --- /dev/null +++ b/src/Kampute.HttpClient/RetryManagement/Strategies/NamespaceDoc.cs @@ -0,0 +1,12 @@ +// Copyright (C) 2024 Kampute +// +// This file is part of the Kampute.HttpClient package and is released under the terms of the MIT license. +// See the LICENSE file in the project root for the full license text. + +namespace Kampute.HttpClient.RetryManagement.Strategies +{ + /// + /// This namespace contains implementations of various retry strategies for HTTP requests. + /// + internal static class NamespaceDoc { } +} diff --git a/src/Kampute.HttpClient/Utilities/NamespaceDoc.cs b/src/Kampute.HttpClient/Utilities/NamespaceDoc.cs new file mode 100644 index 0000000..bd7de8f --- /dev/null +++ b/src/Kampute.HttpClient/Utilities/NamespaceDoc.cs @@ -0,0 +1,13 @@ +// Copyright (C) 2024 Kampute +// +// This file is part of the Kampute.HttpClient package and is released under the terms of the MIT license. +// See the LICENSE file in the project root for the full license text. + +namespace Kampute.HttpClient.Utilities +{ + /// + /// This namespace contains utility classes and extensions for managing + /// shared resources, caching, and asynchronous operations. + /// + internal static class NamespaceDoc { } +} diff --git a/src/Kampute.HttpClient/Utilities/ScopedCollection.cs b/src/Kampute.HttpClient/Utilities/ScopedCollection.cs index 2e67560..f1f9b5d 100644 --- a/src/Kampute.HttpClient/Utilities/ScopedCollection.cs +++ b/src/Kampute.HttpClient/Utilities/ScopedCollection.cs @@ -9,6 +9,7 @@ /// /// Manages items within specific contexts. /// + /// The type of items managed within the scopes. /// /// /// This class facilitates the management of contextual items, which are elements associated with distinct operational contexts, diff --git a/src/Kampute.HttpClient/Utilities/SharedDisposable.cs b/src/Kampute.HttpClient/Utilities/SharedDisposable.cs index 7271ed8..012db17 100644 --- a/src/Kampute.HttpClient/Utilities/SharedDisposable.cs +++ b/src/Kampute.HttpClient/Utilities/SharedDisposable.cs @@ -14,7 +14,7 @@ namespace Kampute.HttpClient.Utilities /// The type of the disposable object. Must be a class that implements . /// /// - /// This class is particularly useful for managing resources that are expensive to create and can be safely shared across different parts + /// This class is particularly useful for managing resources that are expensive to create and can be safely shared across different parts /// of an application. It ensures that the resource remains alive as long as it is needed and is properly cleaned up afterwards. This pattern /// helps prevent resource leaks and promotes efficient resource usage. /// @@ -27,13 +27,14 @@ public sealed class SharedDisposable where T : class, IDisposable { private T? _instance; private int _referenceCount; - private readonly Func? _factory; + private readonly Func _factory; private readonly object _lock = new(); /// /// Initializes a new instance of the class that uses the default constructor of . /// public SharedDisposable() + : this(Activator.CreateInstance) { } @@ -68,7 +69,7 @@ private T IncReferenceCount() lock (_lock) { if (++_referenceCount == 1) - _instance = _factory is not null ? _factory() : (T)Activator.CreateInstance(typeof(T)); + _instance = _factory(); return _instance ?? throw new InvalidOperationException("The shared disposal manager factory failed."); } @@ -110,6 +111,7 @@ internal Reference(SharedDisposable owner) /// /// Gets the instance that owns this reference. /// + /// The owning instance. public SharedDisposable Owner => _owner; /// @@ -135,6 +137,7 @@ public void Dispose() /// Allows implicit conversion of the to the shared resource type. /// /// The reference instance. + /// The shared disposable resource instance. public static implicit operator T(Reference reference) => reference.Instance; } } diff --git a/tests/Kampute.HttpClient.DataContract.Test/Kampute.HttpClient.DataContract.Test.csproj b/tests/Kampute.HttpClient.DataContract.Test/Kampute.HttpClient.DataContract.Test.csproj index aac1829..668c46e 100644 --- a/tests/Kampute.HttpClient.DataContract.Test/Kampute.HttpClient.DataContract.Test.csproj +++ b/tests/Kampute.HttpClient.DataContract.Test/Kampute.HttpClient.DataContract.Test.csproj @@ -10,15 +10,15 @@ - - - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/tests/Kampute.HttpClient.Json.Test/Kampute.HttpClient.Json.Test.csproj b/tests/Kampute.HttpClient.Json.Test/Kampute.HttpClient.Json.Test.csproj index 74348e5..35c8533 100644 --- a/tests/Kampute.HttpClient.Json.Test/Kampute.HttpClient.Json.Test.csproj +++ b/tests/Kampute.HttpClient.Json.Test/Kampute.HttpClient.Json.Test.csproj @@ -10,15 +10,15 @@ - - - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/tests/Kampute.HttpClient.NewtonsoftJson.Test/Kampute.HttpClient.NewtonsoftJson.Test.csproj b/tests/Kampute.HttpClient.NewtonsoftJson.Test/Kampute.HttpClient.NewtonsoftJson.Test.csproj index ac27e64..71a95d2 100644 --- a/tests/Kampute.HttpClient.NewtonsoftJson.Test/Kampute.HttpClient.NewtonsoftJson.Test.csproj +++ b/tests/Kampute.HttpClient.NewtonsoftJson.Test/Kampute.HttpClient.NewtonsoftJson.Test.csproj @@ -10,15 +10,15 @@ - - - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/tests/Kampute.HttpClient.Test/Kampute.HttpClient.Test.csproj b/tests/Kampute.HttpClient.Test/Kampute.HttpClient.Test.csproj index cd846c8..9b7c31b 100644 --- a/tests/Kampute.HttpClient.Test/Kampute.HttpClient.Test.csproj +++ b/tests/Kampute.HttpClient.Test/Kampute.HttpClient.Test.csproj @@ -10,15 +10,15 @@ - - - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/tests/Kampute.HttpClient.Xml.Test/Kampute.HttpClient.Xml.Test.csproj b/tests/Kampute.HttpClient.Xml.Test/Kampute.HttpClient.Xml.Test.csproj index e15107e..abb1ef8 100644 --- a/tests/Kampute.HttpClient.Xml.Test/Kampute.HttpClient.Xml.Test.csproj +++ b/tests/Kampute.HttpClient.Xml.Test/Kampute.HttpClient.Xml.Test.csproj @@ -10,15 +10,15 @@ - - - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive