{"id":21623030,"url":"https://github.com/pandatecham/be-lib-sharedkernel","last_synced_at":"2026-05-11T02:47:52.258Z","repository":{"id":263373068,"uuid":"889556387","full_name":"PandaTechAM/be-lib-sharedkernel","owner":"PandaTechAM","description":"Most common utilities used in every project by PandaTech","archived":false,"fork":false,"pushed_at":"2025-03-18T05:36:34.000Z","size":348,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"development","last_synced_at":"2025-03-18T06:31:56.529Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PandaTechAM.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-11-16T16:21:21.000Z","updated_at":"2025-03-18T05:35:24.000Z","dependencies_parsed_at":"2024-12-20T12:29:37.349Z","dependency_job_id":"25936de9-a69b-48e6-abec-aa2c9bc5a263","html_url":"https://github.com/PandaTechAM/be-lib-sharedkernel","commit_stats":null,"previous_names":["pandatecham/be-lib-sharedkernel"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PandaTechAM%2Fbe-lib-sharedkernel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PandaTechAM%2Fbe-lib-sharedkernel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PandaTechAM%2Fbe-lib-sharedkernel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PandaTechAM%2Fbe-lib-sharedkernel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PandaTechAM","download_url":"https://codeload.github.com/PandaTechAM/be-lib-sharedkernel/tar.gz/refs/heads/development","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244287918,"owners_count":20428896,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-25T00:11:20.193Z","updated_at":"2026-05-11T02:47:47.226Z","avatar_url":"https://github.com/PandaTechAM.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pandatech.SharedKernel\n\nWelcome to the `Pandatech.SharedKernel` NuGet package - a centralized library designed to streamline development across\nall PandaTech projects. This package consolidates shared configurations, utilities, and extensions into a single,\nreusable resource.\n\nAlthough this package is primarily intended for internal use, it is publicly available for anyone who may find it\nuseful. We recommend forking or copying the classes in this repository and creating your own package to suit your needs.\n\nBy leveraging this shared kernel, we aim to:\n\n- Reduce the amount of boilerplate code required to start a new project.\n- Ensure consistency across all PandaTech projects.\n- Simplify the process of updating shared configurations and utilities.\n\n## Scope\n\nThis package currently supports:\n\n- **OpenAPI Configuration** with SwaggerUI and Scalar.\n- **Logging** with Serilog (including ECS, Loki and compact JSON file output, plus automatic log cleanup).\n- **MediatR and FluentValidation** configurations.\n- **Cors Configuration** with easy configuration options.\n- **Resilience Pipelines** for `HttpClient` operations.\n- **Controller Extensions** for mapping old-style MVC controllers.\n- **SignalR Extensions** for adding simple SignalR or distributed SignalR backed with Redis.\n- **OpenTelemetry**: Metrics, traces, and logs with Prometheus support.\n- **Health Checks**: Startup validation and endpoints for monitoring.\n- Various **Extensions and Utilities**, including enumerable, string, dictionary and queryable extensions.\n\n## Prerequisites\n\n- .NET 9.0 SDK or higher\n\n## Installation\n\nTo install the `Pandatech.SharedKernel` package, use the following command:\n\n```bash\ndotnet add package Pandatech.SharedKernel\n```\n\nAlternatively, you can add it via the NuGet Package Manager in Visual Studio, VS Code or Rider.\n\n## Full SharedKernel Demo\n\nThis section demonstrates how to use the `Pandatech.SharedKernel` package in a fully functional application. It includes\nexamples of:\n\n- Comprehensive `appsettings.json` configurations.\n- Environment-specific settings in `appsettings.{Environment}.json`.\n- A complete `Program.cs` implementation with all major features integrated.\n\nFollow this example to set up your project with all the features provided by this library.\n\n### appsettings.json\n\n```json\n{\n    \"OpenApi\": {\n        \"DisabledEnvironments\": [\n            \"Production\"\n        ],\n        \"SecuritySchemes\": [\n            {\n                \"HeaderName\": \"Client-Type\",\n                \"Description\": \"Specifies the client type, e.g., '2'.\"\n            },\n            {\n                \"HeaderName\": \"Authorization\",\n                \"Description\": \"Access token for the API.\"\n            }\n        ],\n        \"Documents\": [\n            {\n                \"Title\": \"Administrative Panel Partners\",\n                \"Description\": \"This document describes the API endpoints for the Administrative Panel Partners.\",\n                \"GroupName\": \"admin-v1\",\n                \"Version\": \"v1\",\n                \"ForExternalUse\": false\n            },\n            {\n                \"Title\": \"Integration\",\n                \"Description\": \"Integration API Endpoints\",\n                \"GroupName\": \"integration-v1\",\n                \"Version\": \"v1\",\n                \"ForExternalUse\": true\n            }\n        ],\n        \"Contact\": {\n            \"Name\": \"Pandatech\",\n            \"Url\": \"https://pandatech.it\",\n            \"Email\": \"info@pandatech.it\"\n        }\n    }\n}\n```\n\n### appsettings.{Environment}.json\n\n```json\n{\n    \"Serilog\": {\n        \"MinimumLevel\": {\n            \"Default\": \"Information\",\n            \"Override\": {\n                \"Microsoft\": \"Information\",\n                \"System\": \"Information\"\n            }\n        }\n    },\n    \"ResponseCrafterVisibility\": \"Private\",\n    \"DefaultTimeZone\": \"Caucasus Standard Time\",\n    \"RepositoryName\": \"be-lib-sharedkernel\",\n    \"ConnectionStrings\": {\n        \"Redis\": \"localhost:6379\",\n        \"PersistentStorage\": \"/persistence\"\n    }\n}\n```\n\n### Program.cs\n\n```csharp\nvar builder = WebApplication.CreateBuilder(args);\n\nbuilder.LogStartAttempt();\nAssemblyRegistry.Add(typeof(Program).Assembly);\n\nbuilder\n   .ConfigureWithPandaVault()\n   .AddSerilog(LogBackend.Loki)\n   .AddResponseCrafter(NamingConvention.ToUpperSnakeCase)\n   .AddOpenApi()\n   .AddOpenTelemetry()\n   .AddMapMinimalApis(AssemblyRegistry.ToArray())\n   .AddControllers(AssemblyRegistry.ToArray())\n   .AddMediatrWithBehaviors(AssemblyRegistry.ToArray())\n   .AddResilienceDefaultPipeline()\n   .MapDefaultTimeZone()\n   .AddDistributedCache(o =\u003e\n   {\n      o.RedisConnectionString = \"redis://localhost:6379\";\n      o.ChannelPrefix = \"app_name:\";\n   })\n   .AddDistributedSignalR(\"redis://localhost:6379\",\"app_name:\") // or .AddSignalR()\n   .AddCors()\n   .AddHealthChecks();\n\n\nvar app = builder.Build();\n\napp\n   .UseRequestLogging()\n   .UseResponseCrafter()\n   .UseCors()\n   .MapMinimalApis()\n   .EnsureHealthy()\n   .MapHealthCheckEndpoints()\n   .MapPrometheusExporterEndpoints()\n   .ClearAssemblyRegistry()\n   .UseOpenApi()\n   .MapControllers();\n\napp.LogStartSuccess();\napp.Run();\n```\n\nFor a deeper dive into each feature, please refer to the following sections.\n\n## OpenAPI\n\n`Microsoft.AspNetCore.OpenApi` is the new standard for creating OpenAPI JSON files. We have adopted this library instead\nof Swashbuckle for generating OpenAPI definitions. Along with this new library, we have integrated `SwaggerUI` and\n`Scalar` to provide user-friendly interfaces in addition to the JSON files.\n\n### Key Features\n\n- **Multiple API Documents:** Easily define and organize multiple API documentation groups.\n- **Enum String Values:** Enum string values are automatically displayed in the documentation, simplifying integration\n  for external partners.\n- **Security Schemes:** Configure security headers directly in your OpenAPI settings.\n\n### Adding OpenAPI to Your Project\n\nTo enable OpenAPI in your project, add the following code:\n\n```csharp\nvar builder = WebApplication.CreateBuilder(args);\nbuilder.AddOpenApi();\nvar app = builder.Build();\napp.UseOpenApi();\napp.Run();\n```\n\nYou can also customize the `AddOpenApi` method with options:\n\n```csharp\nbuilder.AddOpenApi(options =\u003e\n{\n    options.AddSchemaTransformer\u003cCustomSchemaTransformer\u003e();\n});\n```\n\n### Configuration\n\nAdd the following configuration to your `appsettings.json` file:\n\n```json\n{\n    \"OpenApi\": {\n        \"DisabledEnvironments\": [\n            \"Production\"\n        ],\n        \"SecuritySchemes\": [\n            {\n                \"HeaderName\": \"Authorization\",\n                \"Description\": \"Access token for the API.\"\n            }\n        ],\n        \"Documents\": [\n            {\n                \"Title\": \"Admin Panel API\",\n                \"Description\": \"API for administrative functions.\",\n                \"GroupName\": \"admin-v1\",\n                \"Version\": \"v1\",\n                \"ForExternalUse\": false\n            },\n            {\n                \"Title\": \"Integration\",\n                \"Description\": \"Integration API Endpoints\",\n                \"GroupName\": \"integration-v1\",\n                \"Version\": \"v1\",\n                \"ForExternalUse\": true\n            }\n        ],\n        \"Contact\": {\n            \"Name\": \"Pandatech\",\n            \"Url\": \"https://pandatech.it\",\n            \"Email\": \"info@pandatech.it\"\n        }\n    }\n}\n```\n\n### Notes\n\n- **For External Use:** If you set `ForExternalUse: true` for a document, it will be available both within the regular\n  SwaggerUI and a separate SwaggerUI instance. This allows you to provide a dedicated URL to external partners while\n  keeping internal documents private.\n- **Scalar UI Limitations:** Scalar currently does not support multiple documents within a single URL. Consequently, all\n  documents in Scalar will be separated into individual URLs. Support for multiple documents is expected in future\n  Scalar updates.\n\n### Example URLs\n\nBased on the above configuration, the UI will be accessible at the following URLs:\n\n- **Swagger (all documents):** [http://localhost/swagger](http://localhost/swagger)\n- **Swagger (external document only):\n  ** [http://localhost/swagger/integration-v1](http://localhost/swagger/integration-v1)\n- **Scalar (admin document):** [http://localhost/scalar/admin-v1](http://localhost/scalar/admin-v1)\n- **Scalar (integration document):** [http://localhost/scalar/integration-v1](http://localhost/scalar/integration-v1)\n\n## Logging\n\n### Key Features\n\n- **Serilog Integration:** Simplified setup for structured logging using Serilog.\n- **Log Backend Option** Choose between:\n    - `LogBackend.None` (disables file logging completely),\n    - `LogBackend.ElasticSearch` (ECS formatter to file), or\n    - `LogBackend.Loki` (Loki formatter to file), or\n    - `LogBackend.CompactJson` (compact JSON format to file).\n- **Environment-Specific Configuration:**\n    - **Local:** Logs to console.\n    - **Production:** Logs to file (in ECS or Loki format depending on the backend).\n    - **Other Environments:** Logs to both console and file.\n- **Automatic Log Cleanup:** Log files are automatically cleaned up based on the configured retention period.\n- **Log File Location:** Logs are stored in a persistent path defined in your configuration, organized by repository\n  name and environment, under the `logs` directory.\n- **Filtering:** Excludes unwanted logs from Hangfire Dashboard, Swagger, outbox DB commands, and MassTransit health\n  checks.\n- **Request Logging:** Middleware that logs incoming requests and outgoing responses while redacting sensitive\n  information and large payloads.\n- **Outbound Logging Handler:** For capturing outbound `HttpClient` requests (including headers and bodies) with the\n  same redaction rules.\n\n### Adding Logging to Your Project\n\nUse the `AddSerilog` extension when building your `WebApplicationBuilder`. You can specify:\n\n- `logBackend`: One of `None`, `ElasticSearch` (ECS file format), `Loki` (Loki JSON file format) or `CompactJson`.\n- `daysToRetain`: Number of days to keep log files. Older files are automatically removed by the background hosted\n  service.\n\nIn your middleware pipeline, add the request and response logging middleware:\n\n```csharp\n// 1) Synchronous logging with 7-day retention (default). \nbuilder.AddSerilog(LogBackend.Loki);\n\n// 2) Asynchronous logging with 14-day retention and extra properties.\n//    Suitable for high-load (~1000+ RPS per pod) scenarios where slight risk of log loss is acceptable \n//    in exchange for better performance.\nbuilder.AddSerilog(\n    logBackend: LogBackend.Loki,\n    logAdditionalProperties: new Dictionary\u003cstring, string\u003e\n    {\n        [\"ServiceName\"] = \"MyApp\",\n        [\"Environment\"] = \"Staging\"\n    },\n    daysToRetain: 14,\n    asyncSinks: true\n);\n```\n\n\u003e- **Asynchronous Sinks (asyncSinks: true):** Recommended for very high-traffic environments (e.g., 1000+ requests per\n  second per pod) where performance is critical and the possibility of losing a small amount of log data (e.g., on\n  sudden process termination) is acceptable. \u003cbr\u003e\u003cbr\u003e\n\u003e- **Synchronous Sinks (asyncSinks: false):** Recommended if you can handle up to ~1000 requests per second per pod and must\n  retain every log entry without fail. This might incur slightly more overhead but ensures maximum reliability.\n\nConfigure minimal Serilog settings in your environment JSON files as needed, for example in\n`appsettings.{Environment}.json`:\n\n```json\n{\n    \"Serilog\": {\n        \"MinimumLevel\": {\n            \"Default\": \"Information\",\n            \"Override\": {\n                \"Microsoft\": \"Information\",\n                \"System\": \"Information\"\n            }\n        }\n    },\n    \"RepositoryName\": \"be-lib-sharedkernel\",\n    \"ConnectionStrings\": {\n        \"PersistentStorage\": \"/persistence\"\n    }\n}\n```\n\n### Log Cleanup\n\nWhen you call `builder.AddSerilog(..., daysToRetain: X)`, a `LogCleanupHostedService` is automatically registered. This\nhosted service runs periodically to delete log files older than the specified retention period.\n\n### Usage Notes\n\n- **No Direct Sinks to External Systems:** By default, logs are written to local files with ECS or Loki JSON format. You\n  can\n  later push these files to external systems (e.g., via Filebeat, Logstash, Promtail, or any specialized agent).\n- **Optional Enrichment:** You can pass a `Dictionary\u003cstring, string\u003e` to `AddSerilog` to add extra log properties\n  globally:\n    ```csharp\n    builder.AddSerilog(\n        logBackend: LogBackend.Loki,\n        logAdditionalProperties: new Dictionary\u003cstring, string\u003e\n        {\n            {\"ServiceName\", \"MyService\"},\n            {\"ServiceVersion\", \"1.0.0\"}\n         }\n    );    \n    ```\n\n### Startup Logging\n\nThe package provides methods to log application startup events:\n\n- `LogStartAttempt()`: Logs when the application start is attempted.\n- `LogStartSuccess()`: Logs when the application has successfully started, including the initialization time.\n- `LogModuleRegistrationSuccess(moduleName)`: Logs successful registration of a module.\n- `LogModuleUseSuccess(moduleName)`: Logs successful usage of a module.\n\nExample:\n\n```csharp\nvar builder = WebApplication.CreateBuilder(args);\nbuilder.LogStartAttempt();\n// Configure services\nvar app = builder.Build();\n// Configure middleware\napp.UseRequestLogging();\n// Other middleware\napp.LogStartSuccess();\napp.Run();\n```\n\n### Outbound Logging with HttpClient\n\nIn addition to the `RequestLoggingMiddleware` for inbound requests, you can now log **outbound** HTTP calls via an\n`OutboundLoggingHandler`. This handler captures request and response data (including headers and bodies), automatically\nredacting sensitive information (e.g., passwords, tokens).\n\n#### Usage\n\n1. **Register the handler** in your `WebApplicationBuilder`:\n   ```csharp\n   builder.AddOutboundLoggingHandler();\n   ```\n2. **Attach** the handler to any HttpClient registration:\n    ```csharp\n    builder.Services\n       .AddHttpClient(\"RandomApiClient\", client =\u003e\n       {\n           client.BaseAddress = new Uri(\"http://localhost\");\n       })\n       .AddOutboundLoggingHandler();\n    ```\n3. **Check logs:** Outbound requests and responses are now logged with redacted headers and bodies, just like inbound\n   traffic.\n\n\u003e Note: The same redaction rules apply to inbound and outbound calls. Update RedactionHelper if you need to modify the\n\u003e behavior (e.g., adding new sensitive keywords).\n\n## MediatR and FluentValidation Integration\n\n### Key Features\n\n- **MediatR Integration:** Simplifies the implementation of the Mediator pattern for handling commands and queries.\n- **Custom Interfaces for CQRS:** Provides ICommand and IQuery interfaces to facilitate the Command Query Responsibility\n  Segregation (CQRS) pattern.\n- **Validation Behaviors:** Automatically validates requests using FluentValidation before they reach the handler.\n- **FluentValidation Extensions:** Includes custom validators for common scenarios like file size, file type, JSON\n  validity,\n  and XSS sanitization.\n\n### Adding MediatR to Your Project\n\nTo enable MediatR with validation behaviors in your project, add the following code:\n\n```csharp\nvar builder = WebApplication.CreateBuilder(args);\nbuilder.AddMediatrWithBehaviors([typeof(Program).Assembly]);\n```\n\nThis extension method registers MediatR and adds custom pipeline behaviors for validation. It scans the specified\nassemblies for handlers and validators.\n\n### How It Works\n\n**Custom Interfaces for CQRS**\nThe package provides custom interfaces to distinguish between commands and queries, aligning with the CQRS pattern:\n\n- Commands:\n    - `ICommand\u003cTResponse\u003e` and `ICommand`\n    - Handled by `ICommandHandler\u003cTCommand, TResponse\u003e` and `ICommandHandler\u003cTCommand\u003e`\n- Queries:\n    - `IQuery\u003cTResponse\u003e` and `IQuery`\n    - Handled by `IQueryHandler\u003cTQuery, TResponse\u003e` and `IQueryHandler\u003cTQuery\u003e`\n\nThese interfaces help in organizing your application logic and can be extended in the future, for example, to route read\nrequests to replicas and write requests to a primary database.\n\n### Validation Behaviors\n\nTwo custom pipeline behaviors are added to MediatR:\n\n- `ValidationBehaviorWithResponse\u003cTRequest, TResponse\u003e`: Used for requests that expect a response.\n- `ValidationBehaviorWithoutResponse\u003cTRequest, TResponse\u003e`: Used for requests that do not expect a response.\n\nThese behaviors automatically validate the incoming requests using FluentValidation validators before they reach the\nhandler. If validation fails, a `BadRequestException` is thrown with the validation errors.\n\u003e `BadRequestException` is from Pandatech.ResponseCrafter NuGet package\n\n### FluentValidation Extensions\n\nThe package includes extension methods to simplify common validation scenarios:\n\n- File Validations:\n    - HasMaxFileSize(maxFileSizeInMb): Validates that an uploaded file does not exceed the specified maximum size.\n    - FileTypeIsOneOf(allowedFileExtensions): Validates that the uploaded file has one of the allowed file\n      extensions.\n- String Validations:\n    - IsValidJson(): Validates that a string is a valid JSON.\n    - IsXssSanitized(): Validates that a string is sanitized against XSS attacks.\n    - IsEmail(): Validates that a string is a valid email address. Native one is not working correctly.\n    - IsPhoneNumber(): Validates that a string is a valid phone number. Format requires area code to be in `()`.\n    - IsEmailOrPhoneNumber(): Validates that a string is either a valid email address or a valid phone number.\n\n## Cors\n\n### Key Features\n\n- **Non-Production Environment:** Allows all origins for ease of development and testing.\n- **Production Environment**\n    - Restricts origins to a specific list defined in the configurations.\n    - Automatically handles `www` and non-`www` versions of allowed origins.\n    - Supports credentials, all methods and headers, and preflight caching.\n\n### Adding Cors to Your Project\n\nTo enable Cors in your project, add the following code:\n\n```csharp\nvar builder = WebApplication.CreateBuilder(args);\nbuilder.AddCors();\nvar app = builder.Build();\napp.UseCors();\napp.Run();\n```\n\n### Configuration\n\nAdd following to your `appsetings.production.json` file:\n\n```json\n{\n    \"Security\": {\n        \"AllowedCorsOrigins\": \"https://example.com,https://api.example.com\"\n    }\n}\n```\n\n- AllowedCorsOrigins: A comma- or semicolon-separated list of allowed origins. Invalid URLs are automatically filtered\n  out.\n\n## Resilience Pipelines\n\n### Key Features\n\n- **Default Resilience Pipeline:** Provides a pre-configured resilience pipeline with retry, circuit breaker, and\n  timeout\n  policies.\n- **Polly Integration:** Utilizes the Microsoft.Extensions.Http.Resilience library which is built on Polly library for\n  implementing advanced resilience strategies.\n- **Flexible Configuration:** Can be applied globally via WebApplicationBuilder or locally within specific HTTP client\n  configurations.\n- **HTTP Client Resilience:** Enhances the reliability of HTTP client calls by handling transient faults and network\n  issues.\n\n### Adding Resilience Pipelines to Your Project\n\nTo enable the default resilience pipeline in your project, you have 3 options:\n\n1. Global Configuration via `WebApplicationBuilder`\n   This method applies the resilience pipeline to all HTTP clients registered in your application.\n   ```csharp\n   var builder = WebApplication.CreateBuilder(args);\n   builder.AddResilienceDefaultPipeline();\n   ```\n2. Local Configuration within HTTP Client Registration\n   This method applies the resilience pipeline to a specific HTTP client registration.\n   ```csharp\n   builder.Services.AddHttpClient(\"MyHttpClient\")\n    .AddResilienceDefaultPipeline();\n   ```\n3. Configuration within HttpClientService.cs\n    ```csharp\n    public class MyHttpClientService\n    {\n    private readonly ResiliencePipelineProvider\u003cstring\u003e _resiliencePipelineProvider;\n    private readonly HttpClient _httpClient;\n    \n        public MyHttpClientService(ResiliencePipelineProvider\u003cstring\u003e resiliencePipelineProvider, HttpClient httpClient)\n        {\n            _resiliencePipelineProvider = resiliencePipelineProvider;\n            _httpClient = httpClient;\n        }\n    \n        public async Task FooAsync()\n        {\n            var pipeline = _resiliencePipelineProvider.GetDefaultPipeline();\n            var response = await pipeline.ExecuteAsync(() =\u003e _httpClient.GetAsync(\"https://example.com\"));\n        }\n    }\n    ```\n\n### How It Works\n\nThe default resilience pipeline includes the following policies:\n\n- **Retry Policy for 429 (Too Many Requests):** Retries the request up to 5 times with an exponential backoff,\n  respecting\n  the `Retry-After` header if present.\n- **Retry Policy for Network Errors and Timeouts:** Retries network-related failures up to 7 times with an exponential\n  backoff.\n- **Circuit Breaker Policy:** Breaks the circuit when the failure ratio exceeds 50% within a 30-second sampling\n  duration,\n  with a minimum throughput of 200 requests.\n- **Timeout Policy:** Times out requests that take longer than 8 seconds.\n\n## Controller Extensions\n\nFor mapping old style MVC controllers, use `builder.AddControllers()`.\nThe `AddControllers()` method can also accept assembly names as parameters to scan for controllers.\nThe `MapControllers()` method maps the controllers to the application.\n\nExample:\n\n```csharp\nvar builder = WebApplication.CreateBuilder(args);\nbuilder.AddControllers([typeof(Program).Assembly]);\nvar app = builder.Build();\napp.MapControllers();\napp.Run();\n```\n\n## Telemetry Integration\n\nIntegrate OpenTelemetry for observability, including metrics, traces, and logging:\n\n1. Setup:\n    ```csharp\n    var builder = WebApplication.CreateBuilder(args);\n    builder.AddOpenTelemetry();\n    var app = builder.Build();\n    app.MapPrometheusExporterEndpoints();\n    app.Run();\n    ```\n2. Prometheus Endpoints:\n    - Metrics: `url/above-board/prometheus`\n    - Health Metrics: `url/above-board/prometheus/health`\n\n3. OTLP Configuration:\n   To configure the OTLP exporter, ensure the following entries are present in your appsettings{Environment}.json or as\n   environment variables:\n    ```json\n    {\n        \"OTEL_EXPORTER_OTLP_ENDPOINT\": \"http://localhost:4317\"\n    }\n    ```\n4. Included Features:\n    - ASP.NET Core metrics\n    - HTTP client telemetry\n    - Distributed tracing\n    - Logging\n    - Prometheus exporter\n    - OTLP exporter\n    - EF Core telemetry\n\n## HealthChecks\n\n- **Startup Validation:** `app.EnsureHealthy()` performs a health check at startup and terminates the application if it\n  is not healthy.\n- **Endpoints Mapping:** `app.MapHealthCheckEndpoints()` maps default health check endpoints to the application.\n- **Mapped Endpoints:**\n    - Ping Endpoint: `url/above-board/ping`\n    - Health Check Endpoint: `url/above-board/health`\n\nExample:\n\n```csharp\nvar app = builder.Build();\n\napp.EnsureHealthy(); // Startup validation\napp.MapHealthCheckEndpoints(); // Map health check routes\n\napp.Run();\n```\n\n## Additional Extensions and NuGet Packages\n\nThis package includes various extensions and utilities to aid development:\n\n- **Enumerable Extensions:** Additional LINQ methods for collections.\n- **Host Environment Extensions:** Methods to simplify environment checks (e.g., `IsLocal()`, `IsQa()`).\n- **Queryable Extensions:** Extensions for IQueryable, such as conditional `WhereIf`.\n- **Dictionary Extensions:** Utility methods for dictionary manipulation in a performant way like `GetOrAdd` and\n  `TryUpdate`.\n- **String Extensions:** Utility methods for string manipulation.\n- **Time Zone Extensions:** Methods to handle default time zones within your application. Use `.MapDefaultTimeZone()`,\n  which\n  retrieves DefaultTimeZone from `appsettings.json` and sets it as the default time zone.\n- **UrlBuilder:** A utility for building URLs with query parameters.\n- **Language ISO Code Helper:** Validate, query, and retrieve information about ISO language codes.\n\n### Related NuGet Packages\n\n- **Pandatech.Crypto:** Provides cryptographic utilities.\n- **Pandatech.FluentMinimalApiMapper:** Simplifies mapping in minimal APIs.\n- **Pandatech.RegexBox:** A collection of useful regular expressions.\n- **Pandatech.ResponseCrafter:** A utility for crafting consistent API responses.\n- **Pandatech.DistributedCache:** A distributed cache provider for Redis.\n- **Pandatech.FileExporter:** A utility for exporting files.\n\n## License\n\nMIT License\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpandatecham%2Fbe-lib-sharedkernel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpandatecham%2Fbe-lib-sharedkernel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpandatecham%2Fbe-lib-sharedkernel/lists"}