diff --git a/.assets/Nano-Application-Architecture.png b/.assets/Nano-Application-Architecture.png
new file mode 100644
index 00000000..af9dcc99
Binary files /dev/null and b/.assets/Nano-Application-Architecture.png differ
diff --git a/.github/workflows/build-and-deploy.yml b/.github/workflows/build-and-deploy.yml
index 34c2050a..c1c64be4 100644
--- a/.github/workflows/build-and-deploy.yml
+++ b/.github/workflows/build-and-deploy.yml
@@ -8,7 +8,7 @@ on:
- master
env:
APP_NAME: Nano.Library
- VERSION: 10.0.0-rc5
+ VERSION: 10.0.0
jobs:
build-and-deploy:
runs-on: windows-latest
diff --git a/.tests/Tests.Nano.Library/Tests.Nano.Library.csproj b/.tests/Tests.Nano.Library/Tests.Nano.Library.csproj
index c87ef80c..23c8706b 100644
--- a/.tests/Tests.Nano.Library/Tests.Nano.Library.csproj
+++ b/.tests/Tests.Nano.Library/Tests.Nano.Library.csproj
@@ -9,9 +9,9 @@
-
-
-
+
+
+
diff --git a/Nano.All/README.md b/Nano.All/README.md
index 44d7643c..19dbdd41 100644
--- a/Nano.All/README.md
+++ b/Nano.All/README.md
@@ -8,13 +8,13 @@
***
## Table of Contents
-* **[Home](https://github.com/Nano-Core/Nano.Library/tree/master/README.md#nanolibrary)**
+* **[Home](https://github.com/Nano-Core/Nano.Library/blob/master/README.md#nanolibrary)**
* **[Summary](#summary)**
## Summary
Includes all Nano packages bundled into a single package for convenience.
-> π Explore the full **[Nano Documentation](https://github.com/Nano-Core/Nano.Library/tree/master/README.md#nanolibrary)**.
+> π Explore the full **[Nano Documentation](https://github.com/Nano-Core/Nano.Library/blob/master/README.md#nanolibrary)**.
> β οΈ While this package provides everything out of the box, itβs generally recommended to reference individual Nano packages as needed in your application.
> Learn more about **[Nano NuGet Packages](https://github.com/Nano-Core/Nano.Library#nuget-packages)**.
diff --git a/Nano.App.Api/Config/ApiOptions.cs b/Nano.App.Api/Config/ApiOptions.cs
index 86510431..ae58f525 100644
--- a/Nano.App.Api/Config/ApiOptions.cs
+++ b/Nano.App.Api/Config/ApiOptions.cs
@@ -56,6 +56,11 @@ public class ApiOptions : BaseAppOptions
///
public virtual HealthCheckOptions? HealthCheck { get; set; }
+ ///
+ /// Metrics configuration options.
+ ///
+ public virtual MetricsOptions? Metrics { get; set; }
+
///
/// API documentation options.
///
diff --git a/Nano.App.Api/Config/MetricsOptions.cs b/Nano.App.Api/Config/MetricsOptions.cs
new file mode 100644
index 00000000..7bf3fc3a
--- /dev/null
+++ b/Nano.App.Api/Config/MetricsOptions.cs
@@ -0,0 +1,6 @@
+namespace Nano.App.Api.Config;
+
+///
+/// Options for configuring metrics behavior.
+///
+public class MetricsOptions;
\ No newline at end of file
diff --git a/Nano.App.Api/Extensions/ApplicationBuilderExtensions.cs b/Nano.App.Api/Extensions/ApplicationBuilderExtensions.cs
index 568ba7d1..97871a7e 100644
--- a/Nano.App.Api/Extensions/ApplicationBuilderExtensions.cs
+++ b/Nano.App.Api/Extensions/ApplicationBuilderExtensions.cs
@@ -678,4 +678,19 @@ internal static IApplicationBuilder UseNanoHealthChecks(this IApplicationBuilder
return applicationBuilder;
}
+
+ internal static IApplicationBuilder UseNanoMetrics(this IApplicationBuilder applicationBuilder, MetricsOptions? options = null)
+ {
+ ArgumentNullException.ThrowIfNull(applicationBuilder);
+
+ if (options == null)
+ {
+ return applicationBuilder;
+ }
+
+ applicationBuilder
+ .UseOpenTelemetryPrometheusScrapingEndpoint();
+
+ return applicationBuilder;
+ }
}
\ No newline at end of file
diff --git a/Nano.App.Api/Extensions/ServiceCollectionExtensions.cs b/Nano.App.Api/Extensions/ServiceCollectionExtensions.cs
index 767fdbdd..b8fa529a 100644
--- a/Nano.App.Api/Extensions/ServiceCollectionExtensions.cs
+++ b/Nano.App.Api/Extensions/ServiceCollectionExtensions.cs
@@ -29,6 +29,7 @@
using System;
using System.Linq;
using System.Text.Json.Serialization;
+using OpenTelemetry.Metrics;
using Vivet.AspNetCore.RequestTimeZone.Enums;
using Vivet.AspNetCore.RequestTimeZone.Extensions;
using Vivet.AspNetCore.RequestTimeZone.Providers;
@@ -65,8 +66,9 @@ internal static IServiceCollection ConfigureNanoApiServices(this IServiceCollect
.AddNanoFormOptions(options.Hosting.MultipartLimits)
.AddNanoHttpsRedirection(options.Hosting.Http, options.Hosting.Https)
.AddNanoMvc()
+ .AddNanoMetrics()
.AddNanoDocumentation(options.Documentation)
- .AddNanoSelfHealthChecking()
+ .AddNanoStartupHealthCheck()
.AddHttpContextAccessor();
return services;
@@ -460,6 +462,24 @@ internal static IServiceCollection AddNanoMvc(this IServiceCollection services)
return services;
}
+ internal static IServiceCollection AddNanoMetrics(this IServiceCollection services)
+ {
+ ArgumentNullException.ThrowIfNull(services);
+
+ services
+ .AddOpenTelemetry()
+ .WithMetrics(metrics =>
+ {
+ metrics
+ .AddAspNetCoreInstrumentation()
+ .AddHttpClientInstrumentation()
+ .AddRuntimeInstrumentation()
+ .AddPrometheusExporter();
+ });
+
+ return services;
+ }
+
internal static IServiceCollection AddNanoDocumentation(this IServiceCollection services, DocumentationOptions? options = null)
{
ArgumentNullException.ThrowIfNull(services);
@@ -490,7 +510,7 @@ internal static IServiceCollection AddNanoDocumentation(this IServiceCollection
return services;
}
- internal static IServiceCollection AddNanoSelfHealthChecking(this IServiceCollection services)
+ internal static IServiceCollection AddNanoStartupHealthCheck(this IServiceCollection services)
{
ArgumentNullException.ThrowIfNull(services);
diff --git a/Nano.App.Api/Extensions/WebApplicationExtensions.cs b/Nano.App.Api/Extensions/WebApplicationExtensions.cs
index 8d807897..96e678f2 100644
--- a/Nano.App.Api/Extensions/WebApplicationExtensions.cs
+++ b/Nano.App.Api/Extensions/WebApplicationExtensions.cs
@@ -29,6 +29,7 @@ internal static WebApplication ConfigureNanoApiApplication(this WebApplication w
.UseStaticFiles()
.UseCookiePolicy()
.UseRouting()
+ .UseNanoMetrics(options.Metrics)
.UseNanoHttpCorsPolicy(options.HttpPolicyHeaders.Cors)
.UseAuthentication()
.UseAuthorization()
diff --git a/Nano.App.Api/Nano.App.Api.csproj b/Nano.App.Api/Nano.App.Api.csproj
index 6144bd29..f78086bc 100644
--- a/Nano.App.Api/Nano.App.Api.csproj
+++ b/Nano.App.Api/Nano.App.Api.csproj
@@ -4,8 +4,13 @@
-
-
+
+
+
+
+
+
+
diff --git a/Nano.App.Api/NanoApiApplication.cs b/Nano.App.Api/NanoApiApplication.cs
index d7c1ddce..161eb191 100644
--- a/Nano.App.Api/NanoApiApplication.cs
+++ b/Nano.App.Api/NanoApiApplication.cs
@@ -14,7 +14,7 @@ namespace Nano.App.Api;
///
/// Represents a Nano API application.
///
-/// Documentation: Nano Api Application
+/// Documentation: Nano Api Application
public class NanoApiApplication : BaseNanoApplication, IApiApplication
{
///
diff --git a/Nano.App.Api/README.md b/Nano.App.Api/README.md
index f5e5bcb0..b2dfe25e 100644
--- a/Nano.App.Api/README.md
+++ b/Nano.App.Api/README.md
@@ -8,7 +8,7 @@
***
## Table of Contents
-* **[Home](https://github.com/Nano-Core/Nano.Library/tree/master/README.md#nanolibrary)**
+* **[Home](https://github.com/Nano-Core/Nano.Library/blob/master/README.md#nanolibrary)**
* **[Summary](#summary)**
* **[Registration](#registration)**
* **[Variables And Secrets](#variables-and-secrets)**
@@ -37,6 +37,7 @@
* **[Versioning](#versioning)**
* **[Documentation](#documentation)**
* **[Health Checks](#health-checks)**
+ * **[Metrics (OpenTelemetry)](#opentelemetry-metrics)**
* **[Virus Scan](#virus-scan)**
* **[Content Negotiation](#content-negotiation)**
* **[Request Tracing](#request-tracing)**
@@ -49,7 +50,7 @@
* **[Request Validation](#request-validation)**
* **[Request Multipart JSON](#request-multipart-json)**
* **[Response Serialization](#response-serialization)**
-* **[Startup Tasks](#startup-tasks)**
+* **[Startup Tasks](#start-up-tasks)**
## Summary
The `NanoApiApplication` is a ready-to-use application template for building APIs with Nano.
@@ -60,18 +61,18 @@ It also provides convenient static methods to create and configure the applicati
through the `ConfigureServices` method. This design ensures that all core API behaviors are initialized consistently using you configuration, reducing boilerplate code
and simplifying the setup of new API applications.
-> β οΈ Before proceeding, it is highly recommended to familiarize yourself generally with **[Nano Applications](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App)**.
+> β οΈ Before proceeding, it is highly recommended to familiarize yourself generally with **[Nano Applications](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App#nanoapp)**.
The `NanoApiApplication` can operate as either an internal service or an externally accessible API.
As an internal service, it can run behind your network boundary, handling requests from other applications within the system,
-using the built-in **[Nano Api Client](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App#api-client)**.
+using the built-in **[Nano Api Client](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App#api-clients)**.
When exposed as an external API, it sits behind an entry point that manages incoming traffic, providing controlled access to clients while keeping
the internal implementation consistent. This design allows the same application to function in both roles without changing its core configuration or service logic,
supporting flexible deployment scenarios.
-> π Learn more about the overall Nano architecture here: **[Nano Architectures](https://github.com/Nano-Core/Nano.Library#nano-architectures)**.
+> π Learn more about the overall Nano architecture here: **[Nano Architectures](https://github.com/Nano-Core/Nano.Library#%EF%B8%8F-nano-architectures)**.
-Also checkout the **[Api.Blank](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api._Blank)** example, that shows a minimal configured API application.
+Also checkout the **[Api.Blank](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api._Blank)** example, that shows a minimal configured API application.
## Registration
First install the [Nano.App.Api](https://www.nuget.org/packages/Nano.App.Api) NuGet package.
@@ -112,7 +113,7 @@ These variables are required and must be configured for the system to function c
## Configuration
The `App` section in the configuration defines behavior related to the application.
-| Setting | Type | Default | Description |
+| Setting | Type | Default | Description |
| ------------------------- | ---------- | ---------- | ----------------------------------------------------------------------------------------------------------- |
| `Version` | string | 1.0.0.0 | Application version identifier. |
| `ShutdownTimeout` | int | 10 | Number of seconds to wait after a SIGTERM signal before shutting down. |
@@ -124,7 +125,8 @@ The `App` section in the configuration defines behavior related to the applicati
| `TimeZone` | object | null | Timezone configuration options. See **[TimeZone](#timezone)**. |
| `Localization` | object | null | Localization configuration options. See **[Localization](#localization)**. |
| `Documentation` | object | null | API documentation options (Swagger). See **[Documentation](#documentation)**. |
-| `HealthCheck` | object | null | Health-check configuration options. See **[health Check](#health-check)**. |
+| `HealthCheck` | object | null | Health-check configuration options. See **[Health Check](#health-check)**. |
+| `Metrics` | object | null | OpenTelemetry metrics configuration options. See **[Metrics](#opentelemetry-metrics)**. |
| `VirusScan` | object | null | Virus scanning options. See **[Virus Scan](#virus-scan)**. |
| `ErrorHandling` | object | default | Error handling configuration options. See **[Error Handling](#error-handling)**. |
| `Authentication` | object | default | Authentication configuration options. See **[Authentication](#authentication)**. |
@@ -150,7 +152,7 @@ The `App` section in the configuration defines behavior related to the applicati
}
```
-> π‘ Learn more about **[Application Configuration](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App#configuration)** here.
+> π‘ Learn more about **[Application Configuration](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App#configuration)** here.
## Hosting
Hosting configuration specifies how the API is hosted on the Kestrel web server, defining endpoint exposure as well as request handling limits.
@@ -199,7 +201,7 @@ If **[Https](#https)** is also enabled, consider turning on `UseHttpsRedirection
```
-Try it out yourself using the **[Api.Hosting.Http](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Hosting.Http)** example.
+Try it out yourself using the **[Api.Hosting.Http](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Hosting.Http)** example.
## Https
Configuring HTTPS allows the API to communicate over a secure SSL/TLS connection.
@@ -255,8 +257,8 @@ services:
- ../:/root/.dotnet/https
```
-In `Staging` and `Production`, TLS certificates are automatically managed by the [Kubernetes Gateway](https://github.com/Nano-Core/Nano.Azure.Kubernetes/tree/master/Nano.Azure.Kubernetes.Gateway/README.md#nanoazurekubernetesgateway)
-and [Cert-Manager](https://github.com/Nano-Core/Nano.Azure.Kubernetes/tree/master/Nano.Azure.Kubernetes.CertManager/README.md#nanoazurekubernetescertmanager).
+In `Staging` and `Production`, TLS certificates are automatically managed by the [Kubernetes Gateway](https://github.com/Nano-Core/Nano.Azure.Kubernetes/blob/master/Nano.Azure.Kubernetes.Gateway/README.md#nanoazurekubernetesgateway)
+and [Cert-Manager](https://github.com/Nano-Core/Nano.Azure.Kubernetes/blob/master/Nano.Azure.Kubernetes.CertManager/README.md#nanoazurekubernetescertmanager).
Applications that are exposed publicly just need to define a subdomain and create an `HTTPRoute` Kubernetes resource.
@@ -281,7 +283,7 @@ spec:
port: 8080
```
-Try it out yourself using the **[Api.Hosting.Https](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Hosting.Https)** example.
+Try it out yourself using the **[Api.Hosting.Https](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Hosting.Https)** example.
## Routing
Routing in Nano is handled automatically and requires no explicit configuration. Routes are derived from controllers that inherit from the Nano base controllers, which
@@ -312,7 +314,7 @@ Otherwise, it is recommended to specify maximum upload sizes and timeouts to pro
}
```
-Try it out yourself using the **[Api.Hosting.MultipartLimits](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Hosting.MultipartLimits)** example.
+Try it out yourself using the **[Api.Hosting.MultipartLimits](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Hosting.MultipartLimits)** example.
## Http Policy Headers
Configure headers such as HSTS, XSS protection, CSP, CORS, and other policies to secure and control HTTP behavior.
@@ -365,7 +367,7 @@ The header allows you to avoid MIME type sniffing by specifying that the MIME ty
> π Learn more about **[Content Type Options](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Content-Type-Options)**
-Try it out yourself using the **[Api.PolicyHeaders.ContentType](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.PolicyHeaders.ContentTypeOptions)** example.
+Try it out yourself using the **[Api.PolicyHeaders.ContentTypeOptions](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.PolicyHeaders.ContentTypeOptions)** example.
## Referrer Policy
The HTTP Referrer-Policy response header controls how much referrer information (sent with the Referer header) should be included with requests.
@@ -401,7 +403,7 @@ Use `[ReferrerPolicy]` to override the global configuration, if needed.
> π Learn more about **[Referrer Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Referrer-Policy)**
-Try it out yourself using the **[Api.PolicyHeaders.ReferrerPolicy](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.PolicyHeaders.ReferrerPolicy)** example.
+Try it out yourself using the **[Api.PolicyHeaders.ReferrerPolicy](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.PolicyHeaders.ReferrerPolicy)** example.
## Frame Options
The HTTP X-Frame-Options response header can be used to indicate whether a browser should be allowed to render the document
@@ -434,7 +436,7 @@ then the browser will allow other sites to embed this document.
> π Learn more about **[Frame Options Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Frame-Options)**
-Try it out yourself using the **[Api.PolicyHeaders.FrameOptions](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.PolicyHeaders.FrameOptions)** example.
+Try it out yourself using the **[Api.PolicyHeaders.FrameOptions](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.PolicyHeaders.FrameOptions)** example.
## Xss Protection
The HTTP X-XSS-Protection response header was a feature of Internet Explorer, Chrome and Safari that stopped pages from loading
@@ -469,7 +471,7 @@ implement a strong Content-Security-Policy that disables the use of inline JavaS
> π Learn more about **[Xss Protection](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-XSS-Protection)**
-Try it out yourself using the **[Api.PolicyHeaders.XssProtection](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.PolicyHeaders.XssProtection)** example.
+Try it out yourself using the **[Api.PolicyHeaders.XssProtection](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.PolicyHeaders.XssProtection)** example.
## Content Security Policy (CSP)
The HTTP Content-Security-Policy response header allows website administrators to control resources the user agent is allowed to load for a given page.
@@ -926,7 +928,7 @@ If configured, both the `Report-To` and `Reporting-Endpoints` headers are emitte
> π Learn more about **[Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy)**
-Try it out yourself using the **[Api.PolicyHeaders.ContentSecurityPolicy](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.PolicyHeaders.ContentSecurityPolicy)** example.
+Try it out yourself using the **[Api.PolicyHeaders.ContentSecurityPolicy](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.PolicyHeaders.ContentSecurityPolicy)** example.
## Cors
Cross-Origin Resource Sharing (CORS) is an HTTP-header-based security mechanism that allows a server to authorize web browsers to load resources
@@ -973,7 +975,7 @@ Use `[EnableCors]` and `[DisableCors]` to override the global configuration, if
> π Learn more about **[Hsts](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS)**
-Try it out yourself using the **[Api.PolicyHeaders.Cors](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.PolicyHeaders.Cors)** example.
+Try it out yourself using the **[Api.PolicyHeaders.Cors](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.PolicyHeaders.Cors)** example.
## Strict Transport Security (Hsts)
HTTP Strict Transport Security (HSTS) is a web security policy mechanism that forces browsers to interact with websites solely through secure HTTPS connections.
@@ -998,7 +1000,7 @@ HTTP Strict Transport Security (HSTS) is a web security policy mechanism that fo
> π Learn more about **[Hsts](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Strict-Transport-Security)**
-Try it out yourself using the **[Api.PolicyHeaders.Hsts](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.PolicyHeaders.Hsts)** example.
+Try it out yourself using the **[Api.PolicyHeaders.Hsts](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.PolicyHeaders.Hsts)** example.
## Robots
The `X-Robots-Tag` response header defines how crawlers should index URLs. While not part of any specification, it is a de-facto standard method
@@ -1032,7 +1034,7 @@ for communicating with search bots, web crawlers, and similar user agents.
> π Learn more about **[X-Robots-Tag](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Robots-Tag)**
-Try it out yourself using the **[Api.PolicyHeaders.Robots](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.PolicyHeaders.Robots)** example.
+Try it out yourself using the **[Api.PolicyHeaders.Robots](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.PolicyHeaders.Robots)** example.
## Forwarded Headers
When connecting through a HTTP proxy (or load balancer), server logs will only contain the IP address, host address, and protocol of the proxy;
@@ -1079,7 +1081,7 @@ Therefore, this approach is safe only if your traffic always passes through a tr
> π Learn more about **[Forwarded Headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Forwarded)**
-Try it out yourself using the **[Api.PolicyHeaders.ForwardedHeaders](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.PolicyHeaders.ForwardedHeaders)** example.
+Try it out yourself using the **[Api.PolicyHeaders.ForwardedHeaders](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.PolicyHeaders.ForwardedHeaders)** example.
## Response Cache
The HTTP cache stores a response associated with a request and reuses the stored response for subsequent requests.
@@ -1110,7 +1112,7 @@ restore the session based on the cookie, query the DB for results, or render the
> π Learn more about **[Response Caching](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Caching)**
-Try it out yourself using the **[Api.ResponseCache](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.ResponseCache)** example.
+Try it out yourself using the **[Api.ResponseCache](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.ResponseCache)** example.
## Response Compression
HTTP response compression is a technique used to reduce the size of data sent from a web server to a client (usually a browser).
@@ -1132,7 +1134,7 @@ By shrinking the payload, it improves website loading speeds, reduces bandwidth
> π Learn more about **[Response Compression](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Compression)**
-Try it out yourself using the **[Api.ResponseCompression](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.ResponseCompression)** example.
+Try it out yourself using the **[Api.ResponseCompression](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.ResponseCompression)** example.
## Session
Adds session state support to the application, allowing user-specific data to persist across requests.
@@ -1154,7 +1156,7 @@ Cookie name: `.AspNetCore.Session`
}
```
-Try it out yourself using the **[Api.Session](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Session)** example.
+Try it out yourself using the **[Api.Session](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Session)** example.
## Cookies
Cookies in Nano are pre-configured for security and cannot be customized. This ensures that all cookies follow best practices by default.
@@ -1171,7 +1173,7 @@ When a cookie is created, Nano automatically enforces these settings.
If a cookieβs options already match the policy or are stricter, they remain unchanged.
However, if a cookieβs options violate the policy, the middleware adjusts them to ensure they conform before the response is sent to the client.
-Try it out yourself using the **[Api.Cookies](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Cookies)** example.
+Try it out yourself using the **[Api.Cookies](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Cookies)** example.
## TimeZone
Nano supports built-in methods for specifying the timezone when making requests.
@@ -1187,8 +1189,7 @@ To specify the timezone in a request, you can use one of the following methods:
* Querystring parameter (`tz=Europe/Copenhagen`)
* Cookie (`.AspNetCore.TimeZone=Europe/Copenhagen`)
-When using layered Nano APIs, the `tz` header is automatically propagated across all layers when leveraging
-the built-in [Nano Api Client](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App#api-client).
+When using layered Nano APIs, the `tz` header is automatically propagated across all layers when leveraging the built-in [Nano Api Clients](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App#api-clients).
To easily obtain the current date and time, use the following properties on `DateTimeInfo`:
@@ -1211,9 +1212,9 @@ Cookie name: `.AspNetCore.TimeZone`
}
```
-> π Learn more about **[Request TimeZone](https://github.com/vivet/Vivet.AspNetCore/tree/master/Vivet.AspNetCore.RequestTimeZone#vivetaspnetcorerequesttimezone)**.
+> π Learn more about **[Request TimeZone](https://github.com/vivet/Vivet.AspNetCore/blob/master/Vivet.AspNetCore.RequestTimeZone#vivetaspnetcorerequesttimezone)**.
-Try it out yourself using the **[Api.TimeZone](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.TimeZone)** example.
+Try it out yourself using the **[Api.TimeZone](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.TimeZone)** example.
## Localization
Nano provides built-in support for specifying the language when making requests.
@@ -1223,8 +1224,7 @@ To specify the language for a request, you can use one of the following methods:
* Query parameter (```culture=da-DK```)
* Cookie (`.AspNetCore.Culture=c=da-DK|uic=da-DK`)
-When using layered Nano APIs, the `Accept-Language` header is automatically propagated across all layers when leveraging
-the built-in [Nano Api Client](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App#api-client).
+When using layered Nano APIs, the `Accept-Language` header is automatically propagated across all layers when leveraging the built-in [Nano Api Client](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App#api-clients).
Cookie name: `.AspNetCore.Culture`
@@ -1245,7 +1245,7 @@ Cookie name: `.AspNetCore.Culture`
> π Learn more about **[Request Localization](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization)**.
-Try it out yourself using the **[Api.Localization](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Localization)** example.
+Try it out yourself using the **[Api.Localization](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Localization)** example.
## Versioning
API versioning in **Nano** requires no additional configuration. It leverages the built-in versioning support provided by ASP.NET Core.
@@ -1272,7 +1272,7 @@ to the other veresion providers.
> Managing multiple API versions quickly adds complexity and maintenance overhead. Whenever possible, prefer evolving the API in a backward-compatible way
so existing clients continue to work without requiring new versions. Use versioning only in rare cases where breaking changes are unavoidable.
-Try it out yourself using the **[Api.Versioning](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Versioning)** example.
+Try it out yourself using the **[Api.Versioning](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Versioning)** example.
## Documentation
When documentation is enabled in the configuration, the API's web-based documentation interface (Swagger) is available at `/docs`.
@@ -1316,11 +1316,20 @@ When configuring a strict CSP policy, add the following style hash: `"sha256-RL3
> π Learn more about **[Swashbuckle.AspNetCore](https://github.com/domaindrivendev/Swashbuckle.AspNetCore)**.
-Try it out yourself using the **[Api.Documentation](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Documentation)** example.
+Try it out yourself using the **[Api.Documentation](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Documentation)** example.
## Health Checks
When health checks are enabled in the configuration, a `/healthz` endpoint is exposed.
+There are no configuration options required for health checks. You can simply enable health-checks by adding an empty configuration object as shown below.
+
+```json
+"App": {
+ "HealthCheck": {
+ }
+}
+```
+
A _self_ startup health check is performed to await the completion of all pending startup tasks before the application is reported as ready.
As additional Nano providers and services are added to the application, they will automatically appear in the health checks and report their status,
if configured with health-check enabled.
@@ -1344,25 +1353,49 @@ Dependencies between services are represented as a tree of health checks. If any
to the configured rules, affecting the overall health status of the application. This makes it easy to monitor the health of all components and dependencies
in a consistent and centralized way.
-There are no configuration options required for health checks. You can simply enable health-checks by adding an empty configuration object as shown below.
-
-```json
-"App": {
- "HealthCheck": {
- }
-}
-```
-
It is also possible to add health checks for custom services. Simply register the health check during application startup in `ConfigureServices(...)`, and it will
run alongside the built-in health checks provided by Nano.
> π Learn more about **[AspNetCore.Diagnostics.HealthChecks](https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks)**.
-Try it out yourself using the **[Api.HealthChecks](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.HealthChecks)** example.
+Try it out yourself using the **[Api.HealthChecks](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.HealthChecks)** example.
> π‘ Health Checks can also serve as an availability check mechanism.
The health check example also demonstrates how to configure availability monitoring using _Azure Application Insights_.
+## Metrics (OpenTelemetry)
+When health checks are enabled in the configuration, a `/metrics` endpoint is exposed.
+
+The endpoint provides Prometheus-compatible metrics collected through OpenTelemetry, including ASP.NET Core request metrics, HTTP client metrics, and .NET runtime
+metrics. These metrics can be scraped by Azure Managed Prometheus and visualized in Grafana dashboards.
+
+There are no configuration options required for metrics. You can simply enable metrics by adding an empty configuration object as shown below.
+
+```json
+"App": {
+ "Metrics": {
+ }
+}
+```
+
+A Kubernetes `ServiceMonitor` is required to configure Prometheus scraping for the application metrics endpoint.
+
+```yaml
+apiVersion: azmonitoring.coreos.com/v1
+kind: ServiceMonitor
+metadata:
+ name: %SERVICE_NAME%-monitor
+ namespace: %KUBERNETES_NAMESPACE%
+spec:
+ selector:
+ matchLabels:
+ app.kubernetes.io/name: %SERVICE_NAME%
+ endpoints:
+ - port: http
+ path: /metrics
+ interval: 1m
+```
+
## Virus Scan
Nano provides built-in virus scanning through a connected `ClamAV` service.
@@ -1370,7 +1403,7 @@ When configured, all uploaded files are automatically processed through the Clam
If any uploaded file is found to contain a virus, the request is rejected and a `500 Internal Server Error` is returned. The response includes a message indicating
the name of the virus detected and which file(s) triggered the scan.
-> π Learn more about **[ClamAV Virus Scan](https://github.com/Nano-Core/Nano.Kubernetes/tree/master/Nano.Azure.Kubernetes/Nano.Azure.Kubernetes.ClamAV/README.md#nanoazurekubernetesclamav)
+> π Learn more about **[ClamAV Virus Scan](https://github.com/Nano-Core/Nano.Azure.Kubernetes/blob/master/Nano.Azure.Kubernetes.ClamAV/README.md#nanoazurekubernetesclamav)
This feature ensures that all file uploads are automatically checked for malware, providing an extra layer of security for your application. By integrating ClamAV scanning
into the middleware pipeline, Nano helps enforce security best practices and prevents potentially harmful files from entering your system.
@@ -1396,9 +1429,9 @@ into the middleware pipeline, Nano helps enforce security best practices and pre
}
```
-> π Learn more about **[Request Virus Scan](https://github.com/vivet/Vivet.AspNetCore/tree/master/Vivet.AspNetCore.RequestVirusScan#vivetaspnetcorerequestvirusscan)**.
+> π Learn more about **[Request Virus Scan](https://github.com/vivet/Vivet.AspNetCore/blob/master/Vivet.AspNetCore.RequestVirusScan#vivetaspnetcorerequestvirusscan)**.
-Try it out yourself using the **[Api.VirusScan](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.VirusScan)** example.
+Try it out yourself using the **[Api.VirusScan](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.VirusScan)** example.
## Content Negotiation
Content negotiation allows clients to request a specific response format via the `Accept` header.
@@ -1408,11 +1441,11 @@ such as when returning files. If `Accept` header is omitted from the request, Na
No configuration or additional setup is required.
-Try it out yourself using the **[Api.ContentNegotiation](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.ContentNegotiation)** example.
+Try it out yourself using the **[Api.ContentNegotiation](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.ContentNegotiation)** example.
## Request Tracing
A `X-Request-Id` is generated by the first Nano instance encountered in the architecture and is propagated through all layers of the system.
-When using layered Nano APIs with **[Nano Api Client](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App/README.md#api-client)**, the `X-Request-Id` is
+When using layered Nano APIs with **[Nano Api Client](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App/README.md#api-clients)**, the `X-Request-Id` is
automatically passed along. It can also be set by the frontend, which is recommended to ensure that every layer uses the same identifier.
In controllers deriving from `BaseController`, the `X-Request-Id` header value is accessible via the `RequestId` property.
@@ -1420,10 +1453,10 @@ The `X-Request-Id` is also added to the http response, so the consumer can see i
No configuration or additional setup is required.
-When **[Logging](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Logging/README.md#nanologging)** is enabled, Nano adds the `X-Request-Id` to all logs for endpoint requests and responses,
+When **[Logging](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Logging/README.md#nanologging)** is enabled, Nano adds the `X-Request-Id` to all logs for endpoint requests and responses,
enabling request-level tracing and correlation.
-You can try this out using the **[Api.RequestTracing](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.RequestTracing)** example.
+You can try this out using the **[Api.RequestTracing](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.RequestTracing)** example.
## Error Handling
This configuration section is required and will automatically be populated if omitted.
@@ -1444,7 +1477,7 @@ Nano includes a centralized error handling middleware that catches all unhandled
consistent HTTP error responses with appropriate status codes. All error responses are written using `ProblemDetails`, in accordance
with [https://datatracker.ietf.org/doc/html/rfc7807](https://datatracker.ietf.org/doc/html/rfc7807).
-Additionally, when **[Logging](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Logging/README.md#nanologging)** is registered with the application,
+Additionally, when **[Logging](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Logging/README.md#nanologging)** is registered with the application,
the error is logged using the configured provider.
Nano provides built-in mappings between common exception types and HTTP error responses.
@@ -1466,11 +1499,11 @@ Nano provides built-in mappings between common exception types and HTTP error re
The exceptions above may be thrown anywhere in the application, and the Nano error handling middleware will automatically construct the appropriate `ProblemDetails` response.
Nano supports any HTTP status code as long as `ProblemDetails` is used. This also enables proper error propagation when using Nano in a layered architecture
-with the **[Nano Api Client](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App/README.md#api-client)**. When returning custom error responses directly from controllers,
+with the **[Nano Api Client](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App/README.md#api-clients)**. When returning custom error responses directly from controllers,
always return `ProblemDetails` or no response body. Returning custom objects for error responses will not work in a layered Nano architecture,
as the API client can only propagate `ProblemDetails` and will otherwise fall back to a generic `500 Internal Server Error`.
-Try it out yourself using the **[Api.ErrorHandling](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.ErrorHandling)** example.
+Try it out yourself using the **[Api.ErrorHandling](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.ErrorHandling)** example.
## Static Files
Static Files are served directly by the web host without passing through the endpoint pipeline. Common static assets such as
@@ -1480,7 +1513,7 @@ Static files must always be placed in the `wwwroot` folder.
This is enabled by default and requires no additional configuration.
-Try it out yourself using the **[Api.StaticFiles](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.StaticFiles)** example.
+Try it out yourself using the **[Api.StaticFiles](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.StaticFiles)** example.
## Authentication
Nano supports two built-in authentication schemes, JWT and API key authentication. If no authentication schemes has been configured, all endpoints will be accessible anonymously by default.
@@ -1492,7 +1525,7 @@ identity data is passed to Nano (e.g., via external sign-in or sign-up). Nano wi
In Nano, authentication can be either with an identity store to manage user data, or without - transient, relying on external providers without storing identity information.
When your application needs to manage usernames, passwords, roles, permissions, or other persistent user data, you should configure
-**[Data Identity](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md#identity)**. This enables Nano to store and maintain user credentials and claims in a
+**[Data Identity](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md#identity)**. This enables Nano to store and maintain user credentials and claims in a
centralized identity store. Roles and claims can then be automatically loaded for each user, simplifying access control and authorization across your application.
With transient authentication, users authenticate through external providers, and a Nano JWT tokens are generated for use in subsequent requests. Roles and claims
@@ -1513,7 +1546,7 @@ Transient roles and claims may also be added when using persistent authenticatio
legal name at login and add it as a transient claim, rather than storing it permanently in the identity system. This approach ensures that certain information is always
current without the need to update persistent claims when data changes.
-> β οΈ API key authentication is only supported when using the built-in identity store, and is configured as part of **[Data Identity](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md#identity)**.
+> β οΈ API key authentication is only supported when using the built-in identity store, and is configured as part of **[Data Identity](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md#identity)**.
The following configuration is available for authentication.
@@ -1668,7 +1701,7 @@ The `IAuthRootRepository` contains just a single method.
| ---------------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------- |
| `LogInRootAsync` | logInRoot | Signs in the admin/root user using credentials. The credentials must match the root username and password in the configuration. |
-Try it out yourself using the **[Api.Authentication.RootLogin](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Authentication.RootLogin)** example.
+Try it out yourself using the **[Api.Auth.RootLogin](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Auth.RootLogin)** example.
The most basic and commonly used authentication method is logging in with credentials, a username and password, validated against the configured identity store.
@@ -1682,7 +1715,7 @@ The `IAuthIdentityRepository` provides the following methods to support this fun
| `LogInRefreshAsync` | logInRefresh | Refreshes an existing access token using a valid refresh token, generating a new JWT and refresh token. |
| `LogOutAsync` | userId, appId | Logs out the current user. |
-Try it out yourself using the **[Api.Data.Identity.Auth.Jwt](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.Identity.Auth.Jwt)** example.
+Try it out yourself using the **[Api.Data.Identity.Auth.Jwt](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.Identity.Auth.Jwt)** example.
The `IAuthIdentityRepository` supports external authentication backed by the identity store, as shown in the table above. In contrast, the `IAuthTransientRepository`, shown in the table below,
also supports external authentication but is designed for transient logins without persistence and provides dedicated methods for external transient authentication.
@@ -1789,17 +1822,17 @@ intermediate steps, and then use the resulting authentication data together with
Try out external authentication yourself using one of these examples.
-* **[Api.Data.Identity.Auth.External.Custom](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.Identity.Auth.External.Custom)**
-* **[Api.Data.Identity.Auth.External.Facebook](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.Identity.Auth.External.Facebook)**
-* **[Api.Data.Identity.Auth.External.Google](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.Identity.Auth.External.Google)**
-* **[Api.Data.Identity.Auth.External.Microsoft](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.Identity.Auth.External.Microsoft)**
+* **[Api.Data.Identity.Auth.External.Custom](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.Identity.Auth.External.Custom)**
+* **[Api.Data.Identity.Auth.External.Facebook](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.Identity.Auth.External.Facebook)**
+* **[Api.Data.Identity.Auth.External.Google](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.Identity.Auth.External.Google)**
+* **[Api.Data.Identity.Auth.External.Microsoft](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.Identity.Auth.External.Microsoft)**
...or the equivalent transient examples.
-* **[Api.Auth.External.Custom](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Auth.External.Custom)**
-* **[Api.Auth.External.Facebook](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Auth.External.Facebook)**
-* **[Api.Auth.External.Google](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Auth.External.Google)**
-* **[Api.Auth.External.Microsoft](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Auth.External.Microsoft)**
+* **[Api.Auth.External.Custom](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Auth.External.Custom)**
+* **[Api.Auth.External.Facebook](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Auth.External.Facebook)**
+* **[Api.Auth.External.Google](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Auth.External.Google)**
+* **[Api.Auth.External.Microsoft](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Auth.External.Microsoft)**
All authentication repositories are leveraged by the `BaseAuthController` when implemented to expose authentication endpoints. In most cases, you do not need to interact with
the repositories directly. Using the controller provides a consistent, simplified interface to access all configured authentication actions, ensuring that authentication flows are
@@ -1840,7 +1873,7 @@ All the `HttpContext` extension methods returns null, if not authenticated.
The refresh token may be used to extend the access-token when expired.
Nano also supports authentication using an API key, provided in the `X-Api-Key` header. This requires
-**[Data Identity](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md#identity)** to be configured for API keys. When an API key is included in the HTTP header,
+**[Data Identity](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md#identity)** to be configured for API keys. When an API key is included in the HTTP header,
Nano authenticates the request using `ApiKeyAuthenticationHandler`.
Having both JWT and API Key authentication enabled side by side is perfectly valid. Nano will route each incoming request to the appropriate authentication handler based on the
@@ -1850,7 +1883,7 @@ In a layered architecture, when using API key authentication, the Kubernetes gat
validate the API key by calling an authentication endpoint: `http://{app-name}/auth/login/apikey`, and exchanging it for a JWT token that can be forwarded to your backend service. Without
this, services behind the gateway won't automatically authenticate API-key requests. Nano comes with a built-in endpoint when both API key and JWT has been configured, that can be used.
-Try it out yourself using the **[Api.Data.Identity.Auth.ApiKey](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.Identity.Auth.ApiKey)** example.
+Try it out yourself using the **[Api.Data.Identity.Auth.ApiKey](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.Identity.Auth.ApiKey)** example.
## Authorization
Nano supports authorization using either a JWT token or an API key. JWT tokens are provided in the `Authorization` header, while API keys are provided in
@@ -1858,7 +1891,7 @@ the `X-Api-Key` header. If both are configured and both headers are present in a
an application, Nano allows _anonymous_ access by default.
When building layered Nano applications, the `Authorization` header is automatically propagated between applications when using the built-in
-[Nano Api Client](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App#api-client). This ensures that the authenticated context is preserved
+[Nano Api Client](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App#api-clients). This ensures that the authenticated context is preserved
across application boundaries.
In Nano, _claims_ are primarily used for carrying user information, while _roles_ are used for authorization. Nano can be extended to support any kind of custom
@@ -1866,7 +1899,7 @@ authorization strategies. For example, you can override the `[Authorize]` attrib
during application startup. By default, however, Nano base controllers rely on role-based authorization. See [Controllers](#controllers) for details on which
roles are required for specific base controllers and actions.
-Try it out yourself using the **[Api.Authorization](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.Identity.Auth.ApiApi.AuthorizationKey)** example.
+Try it out yourself using the **[Api.Authorization](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Authorization)** example.
## Api Clients
Nano API clients provide a structured way to communicate with other Nano API applications. They are designed to simplify service-to-service communication while maintaining
@@ -1878,7 +1911,7 @@ into the business logic. Responses and errors are propagated in a predictable wa
When used together with Nanoβs **[Error Handling](#error-handling)** and `ProblemDetails` support, API clients ensure that errors can flow through multiple layers without being lost
or transformed into generic failures.
-> π Learn more **[Nano Api Clients](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App#api-clients)**
+> π Learn more **[Nano Api Clients](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App#api-clients)**
## Controllers
Nano provides several base controller classes that concrete API controllers are expected to inherit from.
@@ -1917,10 +1950,10 @@ to keep the API surface minimal and explicit.
When exposing entity models mapped from SQL views, use `BaseEntityViewController` base class.
-> β οΈ Entity controllers require **[Nano.Data](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md#nanodata)** to be configured for the application.
+> β οΈ Entity controllers require **[Nano.Data](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md#nanodata)** to be configured for the application.
Each concrete implementation of an entity controller must specify two generic parameters. First, the entity model, which defines the database table and its properties
-that the controller will work with. This model comes from **[Nano Data Models](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data#data-models)** and uses
+that the controller will work with. This model comes from **[Nano Data Models](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data#data-models)** and uses
Entity Framework.
```csharp
@@ -1977,7 +2010,7 @@ Nano entity controllers have two required constructor dependencies and one optio
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ILogger` | Required. Provides logging capabilities for the controller. |
| `IRepository` | Required. Provides methods to get, add, update, delete, and query entity data. |
-| `IEventing` | Optional. If eventing is configured, this allows the controller to publish events from its actions. See **[Nano.Eventing](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Eventing/README.md#nanoeventing)**. |
+| `IEventing` | Optional. If eventing is configured, this allows the controller to publish events from its actions. See **[Nano.Eventing](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Eventing/README.md#nanoeventing)**. |
A controller using the default `Guid` as `TIdentity` would look like this.
@@ -1986,7 +2019,7 @@ public class MyEntitysController(ILogger logger, IRepositor
: BaseEntityController(logger, repository, eventing);
```
-If you have specified a `TIdentity` type when registering **[Nano.Data](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md#nanodata)**, you must also specify the same type
+If you have specified a `TIdentity` type when registering **[Nano.Data](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md#nanodata)**, you must also specify the same type
when deriving your concrete controllers from the Nano base controllers. If `TIdentity` is a `string`, your controller would look like this.
```csharp
@@ -2024,10 +2057,10 @@ When everything is configured and registered, the following endpoints becomes av
> β οΈ Do not set `includeDepth` higher than the configured include depth. **[Response Serialization](#response-serialization)** will only consider the configured value.
-Try it yourself using one of the **[Api.Data Lessons](https://github.com/Nano-Core/Nano.Lessons)**, such as **[Api.Data.MySql](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.MySql)**,
+Try it yourself using one of the **[Api.Data Lessons](https://github.com/Nano-Core/Nano.Lessons)**, such as **[Api.Data.MySql](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.MySql)**,
or any of the other data provider examples.
-When **[Data Identity](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md#identity)** is enabled, Nano provides a specialized base controller for managing
+When **[Data Identity](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md#identity)** is enabled, Nano provides a specialized base controller for managing
entity identities. The `BaseEntityUserController` offers a rich set of methods for creating, updating, and managing user identities within your application.
To use it, derive a concrete implementation of this controller to expose identity-related actions for your application, using a user entity model derived from `BaseEntityUser` or
`BaseEntityUser`. It behaves similarly to other entity controllers but includes additional actions tailored for identity management, such as handling usernames, passwords,
@@ -2101,9 +2134,9 @@ controller.
Endpoints for user refresh tokens are only exposed if JWT authentication is configured. Similarly, endpoints for API keys are only exposed when API key authentication is configured.
-> π Learn more about **[Data Identity](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md#identity)**.
+> π Learn more about **[Data Identity](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md#identity)**.
-Try it yourself using the **[Api.Data.Identity](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.Identity)** example.
+Try it yourself using the **[Api.Data.Identity](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.Identity)** example.
Nano includes the `BaseAuthController` and `BaseAuthController` classes to handle authentication-related operations. To expose authentication endpoints in your API,
simply derive a concrete controller from one of these base classes. There is no need to implement any actions in your derived controller, as all necessary functionality is provided.
@@ -2141,9 +2174,9 @@ The following endpoints are available.
| `/api/audit/query/first` | GET, POST | query, criteria, includeDepth | reader | Retrieves the first entity matching the specified criteria. |
| `/api/audit/query/count` | GET, POST | criteria, includeDepth | reader | Gets the total count of entities matching the specified criteria. |
-> π Learn more about **[Data Audit](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md#audit)**.
+> π Learn more about **[Data Audit](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md#audit)**.
-Try it yourself using the **[Api.Data.Audit](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.Audit)**, or any of the other data provider examples.
+Try it yourself using the **[Api.Data.Audit](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.Audit)**, or any of the other data provider examples.
## Request Validation
When deriving a controller from `BaseController`, model validation is automatically enabled. Validation is based on the attributes applied to model properties. If
@@ -2181,7 +2214,7 @@ while the controller receives fully bound and validated models.
> β οΈ Make sure the JSON field name matches the name of the model parameter in your action.
-Try it out yourself using the **[Api.MultipartJson](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.MultipartJson)** example.
+Try it out yourself using the **[Api.MultipartJson](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.MultipartJson)** example.
## Response Serialization
Nano uses `Newtonsoft.Json` for serialization and deserialization. It supports all built-in Nano types, types derived from Nano base types,
@@ -2189,7 +2222,7 @@ and all `Geometry` types from `NetTopologySuite`.
The serializer only serializes navigations that is of type `IEntity`, when they are annotated with `IncludeAttribute`. This is to avoid returning unwanted navigation
references, that is automatically added if dependent navigations are loaded separately into the data context. Read more about
-**[Include Annotation](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data.App/README.md#include-annotation)**. Responses that doesn't inherit from `IEntity` will be
+**[Include Annotation](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md#include-annotation)**. Responses that doesn't inherit from `IEntity` will be
serialized normally.
> β οΈ Serialization respects only the configured include depth. Loaded navigations within that depth may in rare cases be returned even if the request `includeDepth` is lower.
@@ -2210,6 +2243,6 @@ is fully initialized before becoming available.
> π‘ When using health checks and startup tasks, configure the Kubernetes readiness probe correctly to prevent unwanted pod restarts.
Keep startup tasks simple and fast to ensure smooth application startup
-> π Learn more about **[Nano Startup Tasks](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App#startup-tasks)**.
+> π Learn more about **[Nano Startup Tasks](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App#startup-tasks)**.
-Try it out yourself using the **[Api.StartupTasks](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.StartupTasks)** example.
+Try it out yourself using the **[Api.StartupTasks](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App#start-up-tasks)** example.
diff --git a/Nano.App.Console/NanoConsoleApplication.cs b/Nano.App.Console/NanoConsoleApplication.cs
index 8764cac8..e0e587aa 100644
--- a/Nano.App.Console/NanoConsoleApplication.cs
+++ b/Nano.App.Console/NanoConsoleApplication.cs
@@ -15,7 +15,7 @@ namespace Nano.App.Console;
/// Represents a Nano console application designed to run as a background service or cron job.
/// Provides an entry point for configuring services and running console-based Nano applications.
///
-/// Documentation: Nano Console Application
+/// Documentation: Nano Console Application
public class NanoConsoleApplication : BaseNanoApplication, IConsoleApplication
{
///
diff --git a/Nano.App.Console/README.md b/Nano.App.Console/README.md
index b3fdf4ad..2d167204 100644
--- a/Nano.App.Console/README.md
+++ b/Nano.App.Console/README.md
@@ -8,14 +8,14 @@
***
## Table of Contents
-* **[Home](https://github.com/Nano-Core/Nano.Library/tree/master/README.md#nanolibrary)**
+* **[Home](https://github.com/Nano-Core/Nano.Library/blob/master/README.md#nanolibrary)**
* **[Summary](#summary)**
* **[Registration](#registration)**
* **[Variables And Secrets](#variables-and-secrets)**
* **[Configuration](#configuration)**
* **[Localization](#localization)**
* **[Exception Handling](#exception-handling)**
- * **[Api Clients](api-clients)**
+ * **[Api Clients](#api-clients)**
* **[Console Workers](#console-workers)**
* **[Startup Tasks](#startup-tasks)**
@@ -31,7 +31,7 @@ It provides a concrete and opinionated implementation tailored specifically for
while still allowing full customization through configuration and the `ConfigureServices` method. This ensures that all core application behaviors are
initialized consistently from configuration, reducing boilerplate code and simplifying the creation of new console applications.
-> β οΈ Before proceeding, it is highly recommended to familiarize yourself generally with **[Nano Applications](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App)**.
+> β οΈ Before proceeding, it is highly recommended to familiarize yourself generally with **[Nano Applications](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App#nanoapp)**.
## Registration
First install the **[Nano.App.Console](https://www.nuget.org/packages/Nano.App.Console)** NuGet package.
@@ -84,7 +84,7 @@ The `App` section in the configuration defines behavior related to the applicati
}
```
-> π Learn more about **[Application Configuration](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App#configuration)** here.
+> π Learn more about **[Application Configuration](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App#configuration)** here.
## Localization
The Nano configuration supports specifying a default `CultureInfo` for console applications, ensuring that culture-sensitive operations
@@ -105,23 +105,23 @@ The `DefaultCultureInfo` will be set to the configured default culture.
## Exception Handling
Exceptions thrown by individual Nano workers are handled internally, ensuring that failures in one worker do not impact the execution of others.
-When a **[Logging Provider](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Logging/README.md#nanologging)** is registered, any worker that fails will automatically log the exception.
+When a **[Logging Provider](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Logging/README.md#nanologging)** is registered, any worker that fails will automatically log the exception.
No additional configuration or setup is required.
-Try it out yourself using the **[Api.ExceptionHandling](https://github.com/Nano-Core/Nano.Lessons/tree/master/Console.ExceptionHandling)** example.
+Try it out yourself using the **[Api.ExceptionHandling](https://github.com/Nano-Core/Nano.Lessons/blob/master/Console.ExceptionHandling)** example.
## Api Clients
Nano API clients provide a consistent and structured way for applications to communicate with other Nano API services.
In console applications, they allow worker processes to establish connections with one or more
-**[Nano API applications](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App.Api/README.md#nanoappapi)**, send requests, and retrieve responses in a reliable and predictable manner.
+**[Nano API applications](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App.Api/README.md#nanoappapi)**, send requests, and retrieve responses in a reliable and predictable manner.
This enables console workers to leverage the functionality of multiple Nano services while keeping service boundaries clear and maintaining consistent
error handling, logging, and response propagation across the system.
> π‘ It's recommended to use anonymous API client methods for console workers to avoid configuring root credentials.
-> π Learn more **[Nano Api Clients](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App#api-clients)**
+> π Learn more **[Nano Api Clients](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App#api-clients)**
## Console Workers
You can implement as many workers as you need by creating classes that implement `IWorker`.
@@ -148,7 +148,7 @@ public class MyWorker(ILogger logger)
You can inject any registered service your worker needs, including scoped services, which will be correctly resolved when the worker is executed.
-Try it out yourself using the **[Console.Workers](https://github.com/Nano-Core/Nano.Lessons/tree/master/Console.Workers)** example.
+Try it out yourself using the **[Console.Workers](https://github.com/Nano-Core/Nano.Lessons/blob/master/Console.Workers)** example.
## Startup Tasks
Nano Console applications supports start-up tasks that execute before the application begins processing requests.
@@ -156,6 +156,6 @@ The console worker won't start until all configured start-up tasks have complete
While start-up tasks are rarely required for console applications, this feature is available to ensure any necessary initialization can be performed before the worker starts.
-> π Learn more **[Nano Startup Tasks](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App#startup-tasks)**.
+> π Learn more **[Nano Startup Tasks](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App#start-up-tasks)**.
-Try it out yourself using the **[Api.StartupTasks](https://github.com/Nano-Core/Nano.Lessons/tree/master/Console.StartupTasks)** example.
+Try it out yourself using the **[Api.StartupTasks](https://github.com/Nano-Core/Nano.Lessons/blob/master/Console.StartupTasks)** example.
diff --git a/Nano.App.Web/NanoWebApplication.cs b/Nano.App.Web/NanoWebApplication.cs
index 19e89a96..18589158 100644
--- a/Nano.App.Web/NanoWebApplication.cs
+++ b/Nano.App.Web/NanoWebApplication.cs
@@ -17,7 +17,7 @@ namespace Nano.App.Web;
///
/// Represents a Nano Web application.
///
-/// Documentation: Nano Web Application
+/// Documentation: Nano Web Application
public class NanoWebApplication : NanoApiApplication, IWebApplication
{
///
diff --git a/Nano.App.Web/README.md b/Nano.App.Web/README.md
index 9f2f8b7d..2f1f244c 100644
--- a/Nano.App.Web/README.md
+++ b/Nano.App.Web/README.md
@@ -10,7 +10,7 @@
***
## Table of Contents
-* **[Home](https://github.com/Nano-Core/Nano.Library/tree/master/README.md#nanolibrary)**
+* **[Home](https://github.com/Nano-Core/Nano.Library/blob/master/README.md#nanolibrary)**
* **[Summary](#summary)**
* **[Registration](#registration)**
* **[Configuration](#configuration)**
@@ -20,7 +20,7 @@
## Summary
Extends the API application with built-in support for Razor Pages and Blazor through registered services and middleware.
-> β οΈ Before proceeding, it is highly recommended to familiarize yourself generally with **[Nano Applications](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App/README.md#nanoapp)**.
+> β οΈ Before proceeding, it is highly recommended to familiarize yourself generally with **[Nano Applications](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App/README.md#nanoapp)**.
## Registration
First install the [Nano.App.Web](https://www.nuget.org/packages/Nano.App.Web) NuGet package.
@@ -48,7 +48,7 @@ Register your custom services in the `ConfigureServices(x => { })` method to ext
The `App` section in the configuration controls application-level behavior, similar to the API application.
Currently, the web application does not add any additional configuration options beyond those available in the API application.
-> π Learn more about **[Nano API Configuration](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App.Api/README.md#configuration)**.
+> π Learn more about **[Nano API Configuration](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App.Api/README.md#configuration)**.
## Razor
Coming...
diff --git a/Nano.App/Abstractions/IApplication.cs b/Nano.App/Abstractions/IApplication.cs
index 9c24b786..c2cbc56f 100644
--- a/Nano.App/Abstractions/IApplication.cs
+++ b/Nano.App/Abstractions/IApplication.cs
@@ -19,7 +19,7 @@ public interface IApplication
/// Provides a fluent lifecycle for configuring services, building, and running the application.
///
///
-/// Documentation: Nano Application
+/// Documentation: Nano Application
///
public interface IApplication : IApplication
where TApp : IApplication
diff --git a/Nano.App/ApiClient/Apis/AuditApi.cs b/Nano.App/ApiClient/Apis/AuditApi.cs
index ed03a934..1389bea9 100644
--- a/Nano.App/ApiClient/Apis/AuditApi.cs
+++ b/Nano.App/ApiClient/Apis/AuditApi.cs
@@ -143,35 +143,6 @@ public async Task>> QueryAsync(Quer
.InvokeAsync, IEnumerable>>(request, cancellationToken) ?? [];
}
- ///
- /// Executes audit/query using a query abstraction.
- ///
- public Task>> QueryAsync(IQuery query, CancellationToken cancellationToken = default)
- where TCriteria : IQueryCriteria, new()
- {
- ArgumentNullException.ThrowIfNull(query);
-
- return this.QueryAsync(new QueryRequest
- {
- Query = query
- }, cancellationToken);
- }
-
- ///
- /// Executes audit/query using a query abstraction with related data.
- ///
- public Task>> QueryAsync(IQuery query, int includeDepth, CancellationToken cancellationToken = default)
- where TCriteria : IQueryCriteria, new()
- {
- ArgumentNullException.ThrowIfNull(query);
-
- return this.QueryAsync(new QueryRequest
- {
- Query = query,
- IncludeDepth = includeDepth
- }, cancellationToken);
- }
-
///
/// Executes audit/query/first to retrieve the first matching audit entry.
///
@@ -186,35 +157,6 @@ public Task>> QueryAsync(IQuery, AuditEntry>(request, cancellationToken);
}
- ///
- /// Executes audit/query/first using a query abstraction.
- ///
- public Task?> QueryFirstAsync(IQuery query, CancellationToken cancellationToken = default)
- where TCriteria : IQueryCriteria, new()
- {
- ArgumentNullException.ThrowIfNull(query);
-
- return this.QueryFirstAsync(new QueryFirstRequest
- {
- Query = query
- }, cancellationToken);
- }
-
- ///
- /// Executes audit/query/first using a query abstraction with related data.
- ///
- public Task?> QueryFirstAsync(IQuery query, int includeDepth, CancellationToken cancellationToken = default)
- where TCriteria : IQueryCriteria, new()
- {
- ArgumentNullException.ThrowIfNull(query);
-
- return this.QueryFirstAsync(new QueryFirstRequest
- {
- Query = query,
- IncludeDepth = includeDepth
- }, cancellationToken);
- }
-
///
/// Executes audit/query/count to count matching audit entries.
///
@@ -232,18 +174,4 @@ public async Task QueryCountAsync(QueryCountRequest r
return count;
}
-
- ///
- /// Executes audit/query/count using criteria.
- ///
- public Task QueryCountAsync(TCriteria criteria, CancellationToken cancellationToken = default)
- where TCriteria : IQueryCriteria, new()
- {
- ArgumentNullException.ThrowIfNull(criteria);
-
- return this.QueryCountAsync(new QueryCountRequest
- {
- Criteria = criteria
- }, cancellationToken);
- }
}
\ No newline at end of file
diff --git a/Nano.App/ApiClient/Apis/EntityApi.cs b/Nano.App/ApiClient/Apis/EntityApi.cs
index a14e2e87..3339c9b7 100644
--- a/Nano.App/ApiClient/Apis/EntityApi.cs
+++ b/Nano.App/ApiClient/Apis/EntityApi.cs
@@ -154,48 +154,6 @@ public async Task> QueryAsync(QueryRequ
.InvokeAsync, IEnumerable>(request, cancellationToken) ?? [];
}
- ///
- /// Executes query for using a query object.
- ///
- /// The entity type.
- /// The query criteria type.
- /// The query object.
- /// The cancellation token.
- /// A collection of matching entities.
- public Task> QueryAsync(IQuery query, CancellationToken cancellationToken = default)
- where TEntity : class, IEntity
- where TCriteria : IQueryCriteria, new()
- {
- ArgumentNullException.ThrowIfNull(query);
-
- return this.QueryAsync(new QueryRequest
- {
- Query = query
- }, cancellationToken);
- }
-
- ///
- /// Executes query for using a query object with include depth.
- ///
- /// The entity type.
- /// The query criteria type.
- /// The query object.
- /// The include depth level.
- /// The cancellation token.
- /// A collection of matching entities.
- public Task> QueryAsync(IQuery query, int includeDepth, CancellationToken cancellationToken = default)
- where TEntity : class, IEntity
- where TCriteria : IQueryCriteria, new()
- {
- ArgumentNullException.ThrowIfNull(query);
-
- return this.QueryAsync(new QueryRequest
- {
- Query = query,
- IncludeDepth = includeDepth
- }, cancellationToken);
- }
-
///
/// Executes query/first for to retrieve the first matching entity by request.
///
@@ -214,48 +172,6 @@ public Task> QueryAsync(IQuery, TEntity>(request, cancellationToken);
}
- ///
- /// Executes query/first for using a query object.
- ///
- /// The entity type.
- /// The query criteria type.
- /// The query object.
- /// The cancellation token.
- /// The first matching entity, or null if none found.
- public Task QueryFirstAsync(IQuery query, CancellationToken cancellationToken = default)
- where TEntity : class, IEntity
- where TCriteria : IQueryCriteria, new()
- {
- ArgumentNullException.ThrowIfNull(query);
-
- return this.QueryFirstAsync(new QueryFirstRequest
- {
- Query = query
- }, cancellationToken);
- }
-
- ///
- /// Executes query/first for using a query object with include depth.
- ///
- /// The entity type.
- /// The query criteria type.
- /// The query object.
- /// The include depth level.
- /// The cancellation token.
- /// The first matching entity, or null if none found.
- public Task QueryFirstAsync(IQuery query, int includeDepth, CancellationToken cancellationToken = default)
- where TEntity : class, IEntity
- where TCriteria : IQueryCriteria, new()
- {
- ArgumentNullException.ThrowIfNull(query);
-
- return this.QueryFirstAsync(new QueryFirstRequest
- {
- Query = query,
- IncludeDepth = includeDepth
- }, cancellationToken);
- }
-
///
/// Executes query/count for to count matching entities by request.
///
@@ -278,26 +194,6 @@ public async Task QueryCountAsync(QueryCountRequest
- /// Executes query/count for to count matching entities by criteria.
- ///
- /// The entity type.
- /// The query criteria type.
- /// The query criteria.
- /// The cancellation token.
- /// The number of matching entities.
- public Task QueryCountAsync(TCriteria criteria, CancellationToken cancellationToken = default)
- where TEntity : class, IEntity
- where TCriteria : IQueryCriteria, new()
- {
- ArgumentNullException.ThrowIfNull(criteria);
-
- return this.QueryCountAsync(new QueryCountRequest
- {
- Criteria = criteria
- }, cancellationToken);
- }
-
#endregion
@@ -321,24 +217,6 @@ public async Task CreateAsync(CreateRequest request, Cancellat
return entityCreated ?? throw new NotFoundException(nameof(entityCreated));
}
- ///
- /// Invokes the 'create' endpoint of the entity in the api.
- ///
- /// The entity type.
- /// The entity to create.
- /// The cancellation token.
- /// The created entity.
- public Task CreateAsync(IEntityCreatable entity, CancellationToken cancellationToken = default)
- where TEntity : class, IEntityCreatable
- {
- ArgumentNullException.ThrowIfNull(entity);
-
- return this.CreateAsync(new CreateRequest
- {
- Entity = entity
- }, cancellationToken);
- }
-
///
/// Invokes the 'create/edit' endpoint of the entity in the api.
///
@@ -357,24 +235,6 @@ public async Task CreateOrEditAsync(CreateOrEditRequest reques
return entityCreated ?? throw new NotFoundException(nameof(entityCreated));
}
- ///
- /// Invokes the 'create/edit' endpoint of the entity in the api.
- ///
- /// The entity type.
- /// The entity to create.
- /// The cancellation token.
- /// The created or edited entity.
- public Task CreateOrEditAsync(IEntityCreatableAndUpdatable entity, CancellationToken cancellationToken = default)
- where TEntity : class, IEntityCreatableAndUpdatable
- {
- ArgumentNullException.ThrowIfNull(entity);
-
- return this.CreateOrEditAsync(new CreateOrEditRequest
- {
- Entity = entity
- }, cancellationToken);
- }
-
///
/// Invokes the 'create/get' endpoint of the entity in the api.
///
@@ -393,24 +253,6 @@ public async Task CreateOrGetAsync(CreateOrGetRequest request,
return entityCreated ?? throw new NotFoundException(nameof(entityCreated));
}
- ///
- /// Invokes the 'create/get' endpoint of the entity in the api.
- ///
- /// The entity type.
- /// The entity to create or get.
- /// The cancellation token.
- /// The created or existing entity.
- public Task CreateOrGetAsync(IEntityCreatable entity, CancellationToken cancellationToken = default)
- where TEntity : class, IEntityCreatable, IEntityIdentity
- {
- ArgumentNullException.ThrowIfNull(entity);
-
- return this.CreateOrGetAsync(new CreateOrGetRequest
- {
- Entity = entity
- }, cancellationToken);
- }
-
///
/// Invokes the 'create/reload' endpoint of the entity in the api.
///
@@ -429,24 +271,6 @@ public Task CreateOrGetAsync(IEntityCreatable entity, Cancella
return entityCreated ?? throw new NotFoundException(nameof(entityCreated));
}
- ///
- /// Invokes the 'create/reload' endpoint of the entity in the api.
- ///
- /// The entity type.
- /// The entity to create and reload.
- /// The cancellation token.
- /// The created entity.
- public Task CreateAndGetAsync(IEntityCreatable entity, CancellationToken cancellationToken = default)
- where TEntity : class, IEntityCreatable, IEntityIdentity
- {
- ArgumentNullException.ThrowIfNull(entity);
-
- return this.CreateAndGetAsync(new CreateAndGetRequest
- {
- Entity = entity
- }, cancellationToken);
- }
-
///
/// Invokes the 'create/many' endpoint of the entity in the api.
///
@@ -463,24 +287,6 @@ await this.api
.InvokeAsync>(request, cancellationToken);
}
- ///
- /// Invokes the 'create/many' endpoint of the entity in the api.
- ///
- /// The entity type.
- /// The entities to create.
- /// The cancellation token.
- /// Operation result.
- public Task CreateManyAsync(IEnumerable entities, CancellationToken cancellationToken = default)
- where TEntity : class, IEntityCreatable
- {
- ArgumentNullException.ThrowIfNull(entities);
-
- return this.CreateManyAsync(new CreateManyRequest
- {
- Entities = entities
- }, cancellationToken);
- }
-
///
/// Invokes the 'create/many' bulk endpoint of the entity in the api.
///
@@ -497,24 +303,6 @@ public Task CreateManyBulkAsync(CreateManyBulkRequest request, Cancella
.InvokeAsync>(request, cancellationToken);
}
- ///
- /// Invokes the 'create/many/bulk' bulk endpoint of the entity in the api.
- ///
- /// The entity type.
- /// The entities to create in bulk.
- /// The cancellation token.
- /// Operation result.
- public Task CreateManyBulkAsync(IEnumerable entities, CancellationToken cancellationToken = default)
- where TEntity : class, IEntityCreatable
- {
- ArgumentNullException.ThrowIfNull(entities);
-
- return this.CreateManyBulkAsync(new CreateManyBulkRequest
- {
- Entities = entities
- }, cancellationToken);
- }
-
#endregion
@@ -539,25 +327,6 @@ public Task CreateManyBulkAsync(IEnumerable entities,
return entityEdited ?? throw new NotFoundException(nameof(entityEdited));
}
- ///
- /// Updates an entity via the 'edit' endpoint using an updatable entity instance.
- /// Route: edit
- ///
- /// The entity type.
- /// The entity containing updated values.
- /// A token to cancel the operation.
- /// The updated entity instance.
- public Task EditAsync(IEntityUpdatable entity, CancellationToken cancellationToken = default)
- where TEntity : class, IEntityUpdatable
- {
- ArgumentNullException.ThrowIfNull(entity);
-
- return this.EditAsync(new EditRequest
- {
- Entity = entity
- }, cancellationToken);
- }
-
///
/// Updates and returns an entity via the 'edit/get' endpoint.
/// Route: edit/get
@@ -577,25 +346,6 @@ public Task CreateManyBulkAsync(IEnumerable entities,
return entityEdited ?? throw new NotFoundException(nameof(entityEdited));
}
- ///
- /// Updates and returns an entity via the 'edit/get' endpoint using an entity instance.
- /// Route: edit/get
- ///
- /// The entity type.
- /// The entity containing updated values.
- /// A token to cancel the operation.
- /// The updated entity instance.
- public Task EditGetAsync(IEntityUpdatable entity, CancellationToken cancellationToken = default)
- where TEntity : class, IEntityUpdatable, IEntityIdentity
- {
- ArgumentNullException.ThrowIfNull(entity);
-
- return this.EditAndGetAsync(new EditAndGetRequest
- {
- Entity = entity
- }, cancellationToken);
- }
-
///
/// Updates multiple entities via the 'edit/many' endpoint.
/// Route: edit/many
@@ -613,25 +363,6 @@ await this.api
.InvokeAsync>(request, cancellationToken);
}
- ///
- /// Updates multiple entities via the 'edit/many' endpoint using entity instances.
- /// Route: edit/many
- ///
- /// The entity type.
- /// The entities to update.
- /// A token to cancel the operation.
- /// A task representing the operation.
- public Task EditManyAsync(IEnumerable entities, CancellationToken cancellationToken = default)
- where TEntity : class, IEntityUpdatable
- {
- ArgumentNullException.ThrowIfNull(entities);
-
- return this.EditManyAsync(new EditManyRequest
- {
- Entities = entities
- }, cancellationToken);
- }
-
///
/// Bulk updates multiple entities via the 'edit/many/bulk' endpoint.
/// Route: edit/many/bulk
@@ -649,25 +380,6 @@ public Task EditManyBulkAsync(EditManyBulkRequest request, Cancellation
.InvokeAsync>(request, cancellationToken);
}
- ///
- /// Bulk updates multiple entities via the 'edit/many/bulk' endpoint using entity instances.
- /// Route: edit/many/bulk
- ///
- /// The entity type.
- /// The entities to update.
- /// A token to cancel the operation.
- /// A task representing the operation.
- public Task EditManyBulkAsync(IEnumerable entities, CancellationToken cancellationToken = default)
- where TEntity : class, IEntityUpdatable
- {
- ArgumentNullException.ThrowIfNull(entities);
-
- return this.EditManyBulkAsync(new EditManyBulkRequest
- {
- Entities = entities
- }, cancellationToken);
- }
-
///
/// Updates entities matching a query via the 'edit/query' endpoint.
/// Route: edit/query
@@ -687,33 +399,6 @@ await this.api
.InvokeAsync, TEntity>(request, cancellationToken);
}
- ///
- /// Updates entities matching a query via the 'edit/query' endpoint using criteria and property updates.
- /// Route: edit/query
- ///
- /// The entity type.
- /// The query criteria type.
- /// Selection criteria for entities to update.
- /// Dictionary of property updates to apply.
- /// A token to cancel the operation.
- /// A task representing the operation.
- public Task EditQueryAsync(TCriteria criteria, IDictionary propertyUpdates, CancellationToken cancellationToken = default)
- where TEntity : class, IEntityDeletable
- where TCriteria : class, IQueryCriteria, new()
- {
- ArgumentNullException.ThrowIfNull(criteria);
- ArgumentNullException.ThrowIfNull(propertyUpdates);
-
- return this.EditQueryAsync(new EditQueryRequest
- {
- Query =
- {
- Criteria = criteria,
- PropertyUpdates = propertyUpdates
- }
- }, cancellationToken);
- }
-
///
/// Bulk (batch) updates entities matching a query via the 'edit/query/bulk' endpoint.
/// Route: edit/query/bulk
@@ -733,33 +418,6 @@ await this.api
.InvokeAsync, TEntity>(request, cancellationToken);
}
- ///
- /// Bulk (batch) updates entities matching a query via the 'edit/query/bulk' endpoint using criteria and property updates.
- /// Route: edit/query/bulk
- ///
- /// The entity type.
- /// The query criteria type.
- /// Selection criteria for entities to update.
- /// Dictionary of property updates to apply.
- /// A token to cancel the operation.
- /// A task representing the operation.
- public Task EditQueryBulkAsync(TCriteria criteria, IDictionary propertyUpdates, CancellationToken cancellationToken = default)
- where TEntity : class, IEntityDeletable
- where TCriteria : class, IQueryCriteria, new()
- {
- ArgumentNullException.ThrowIfNull(criteria);
- ArgumentNullException.ThrowIfNull(propertyUpdates);
-
- return this.EditQueryBulkAsync(new EditQueryBulkRequest
- {
- Query =
- {
- Criteria = criteria,
- PropertyUpdates = propertyUpdates
- }
- }, cancellationToken);
- }
-
#endregion
@@ -883,26 +541,6 @@ await this.api
.InvokeAsync, TEntity>(request, cancellationToken);
}
- ///
- /// Deletes entities matching criteria using the 'delete/query' endpoint.
- ///
- /// The entity type.
- /// The criteria type.
- /// The selection criteria.
- /// A token to cancel the operation.
- /// A task representing the asynchronous operation.
- public Task DeleteQueryAsync(TCriteria criteria, CancellationToken cancellationToken = default)
- where TEntity : class, IEntityDeletable
- where TCriteria : IQueryCriteria, new()
- {
- ArgumentNullException.ThrowIfNull(criteria);
-
- return this.DeleteQueryAsync(new DeleteQueryRequest
- {
- Criteria = criteria
- }, cancellationToken);
- }
-
///
/// Deletes (batch) entities in bulk using a query via the 'delete/query/bulk' endpoint.
///
@@ -921,25 +559,5 @@ await this.api
.InvokeAsync, TEntity>(request, cancellationToken);
}
- ///
- /// Deletes (batch) entities in bulk matching criteria using the 'delete/query/bulk' endpoint.
- ///
- /// The entity type.
- /// The criteria type.
- /// The selection criteria.
- /// A token to cancel the operation.
- /// A task representing the asynchronous operation.
- public Task DeleteQueryBulkAsync(TCriteria criteria, CancellationToken cancellationToken = default)
- where TEntity : class, IEntityIdentity, IEntityDeletable
- where TCriteria : IQueryCriteria, new()
- {
- ArgumentNullException.ThrowIfNull(criteria);
-
- return this.DeleteQueryBulkAsync(new DeleteQueryBulkRequest
- {
- Criteria = criteria
- }, cancellationToken);
- }
-
#endregion
}
\ No newline at end of file
diff --git a/Nano.App/ApiClient/BaseApiClient.cs b/Nano.App/ApiClient/BaseApiClient.cs
index c3decde0..42db32f9 100644
--- a/Nano.App/ApiClient/BaseApiClient.cs
+++ b/Nano.App/ApiClient/BaseApiClient.cs
@@ -21,6 +21,8 @@ public abstract class BaseApiClient(ApiClient apiClient)
public abstract class BaseApiClient(ApiClient apiClient)
where TIdentity : IEquatable
{
+ private readonly ApiClient apiClient = apiClient ?? throw new ArgumentNullException(nameof(apiClient));
+
///
/// Provides access to authentication-related API endpoints.
///
diff --git a/Nano.App/Nano.App.csproj b/Nano.App/Nano.App.csproj
index 0e04e9a1..71fdc1e3 100644
--- a/Nano.App/Nano.App.csproj
+++ b/Nano.App/Nano.App.csproj
@@ -2,7 +2,7 @@
-
+
diff --git a/Nano.App/README.md b/Nano.App/README.md
index 852ba8ec..f2aa4559 100644
--- a/Nano.App/README.md
+++ b/Nano.App/README.md
@@ -10,7 +10,7 @@
***
## Table of Contents
-* **[Home](https://github.com/Nano-Core/Nano.Library/tree/master/README.md#nanolibrary)**
+* **[Home](https://github.com/Nano-Core/Nano.Library/blob/master/README.md#nanolibrary)**
* **[Summary](#summary)**
* **[Environment](#environment)**
* **[Configuration](#configuration)**
@@ -32,11 +32,11 @@ are initialized consistently using you configuration, reducing boilerplate code
Three concrete types application are avaialble in Nano.
-| Application | Documentation | Minimal Example |
-| ------------- | -------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
-| Nano API | [Documentation](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App.Api/README#nanoappapi) | [Example](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api._Blank) |
-| Nano Console | [Documentation](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App.Console/README#nanoappconsole) | [Example](https://github.com/Nano-Core/Nano.Lessons/tree/master/Console._Blank) |
-| Nano Web | [Documentation](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App.Web/README#nanoappweb) | [Example](https://github.com/Nano-Core/Nano.Lessons/tree/master/Web._Blank) |
+| Application | Documentation | Minimal Example |
+| ------------- | ----------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
+| Nano API | [Documentation](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App.Api/README.md#nanoappapi) | [Example](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api._Blank) |
+| Nano Console | [Documentation](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App.Console/README.md#nanoappconsole) | [Example](https://github.com/Nano-Core/Nano.Lessons/blob/master/Console._Blank) |
+| Nano Web | [Documentation](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App.Web/README.md#nanoappweb) | [Example](https://github.com/Nano-Core/Nano.Lessons/blob/master/Web._Blank) |
## Environment
By design, Nano is environment-neutral: it does not rely on environment-specific code or behavior.
@@ -79,14 +79,14 @@ With the `NullLogger`, all log messages are discarded, so no logs are persisted.
This is intended as a safety fallback.
-> π Learn more about **[Nano Logging Providers](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Logging/README.md#nanologging)**.
+> π Learn more about **[Nano Logging Providers](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Logging/README.md#nanologging)**.
## Api Clients
Nano provides a generic API client implementation that allows other Nano applications to seamlessly connect and communicate with your application over HTTP.
This feature is intended for API-based application types. Console applications do not implement API clients, since they do not expose HTTP endpoints, but they can still consume
API clients from other applications. To create an API client, derive from either `BaseApiClient` or `BaseApiClient` and implement the required constructor. If your
-application uses Nano **[Identity](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md#identity)**, you should instead derive from `BaseIdentityApiClient` or
+application uses Nano **[Identity](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md#identity)**, you should instead derive from `BaseIdentityApiClient` or
`BaseIdentityApiClient`, where `TUser` represents the `IEntityUser` model defined in your application and `TIdentity` represents the identity type.
The base classes provide a structured set of methods for invoking built-in Nano API endpoints. They expose controllers and actions through a generic, convention-based approach,
@@ -159,8 +159,8 @@ The application has access to several groups of endpoints exposed as properties
have access to the Identity group. Each group contains endpoints organized by their respective domain and purpose. Endpoints that are not enabled in the API application via configuration
will return a 404 response if invoked. For example, if authentication is disabled and an endpoint from the Auth group is called, the request will result in a 404 response.
-The Entity method group in the API client provides generic methods for working with your **[entity data models](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md#data-models)**
-through the **[Entity Controllers](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App.Api/README.md#controllers)** in your application. It exposes methods for all standard Nano controller
+The Entity method group in the API client provides generic methods for working with your **[entity data models](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md#data-models)**
+through the **[Entity Controllers](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App.Api/README.md#controllers)** in your application. It exposes methods for all standard Nano controller
actions, including get, query, add, edit, and delete. The `TEntity` generic parameter defines the entity type used when invoking a method and also determines the corresponding controller
route segment. For example, using `MyEntity` will target the `/MyEntitys/` route, following Nanoβs controller naming conventions.
@@ -313,7 +313,7 @@ Next, add properties to the request and annotate them with request data attribut
| `[Route]` | Defines route parameters. Multiple properties can use `[Route]`. The optional parameter determines the order in which values are substituted into the route defined by the `[Action]` attribute on the request class. |
| `[Query]` | Defines query string parameters. These should be scalar types. The optional `Name` parameter overrides the query parameter name; otherwise, the property name is used. |
| `[Body]` | Defines the request body. It must be a serializable complex type. Typically, this is a dedicated contract class representing the request payload. Nano automatically serializes it when invoking the request. `NetTopologySuite` geometry types are supported, as well as Nanoβs built-in `Query`, `Pagination`, and `Ordering` types. |
-| `[Form]` | Defines a form field included in a multipart request. Properties must be scalar types or one of the thgese file types: `IFormFile`, `FileInfo`, `FileStream`, `Stream`, or `NamedStream` (including `IEnumerable` variants). β οΈ Complex objects are also supported, but require the use of **[`[FromFormBody]`](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App.Api/README.md#request-multipart-json)** on the controller action. |
+| `[Form]` | Defines a form field included in a multipart request. Properties must be scalar types or one of the thgese file types: `IFormFile`, `FileInfo`, `FileStream`, `Stream`, or `NamedStream` (including `IEnumerable` variants). β οΈ Complex objects are also supported, but require the use of **[`[FromFormBody]`](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App.Api/README.md#request-multipart-json)** on the controller action. |
The updated request example below demonstrates how each attribute can be used in practice.
diff --git a/Nano.Common/Nano.Common.csproj b/Nano.Common/Nano.Common.csproj
index 10683d61..68a71ff1 100644
--- a/Nano.Common/Nano.Common.csproj
+++ b/Nano.Common/Nano.Common.csproj
@@ -1,17 +1,17 @@
ο»Ώ
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Nano.Common/README.md b/Nano.Common/README.md
index 9438a32d..65e1d0f2 100644
--- a/Nano.Common/README.md
+++ b/Nano.Common/README.md
@@ -10,11 +10,11 @@
***
## Table of Contents
-* **[Home](https://github.com/Nano-Core/Nano.Library/tree/master/README.md#nanolibrary)**
+* **[Home](https://github.com/Nano-Core/Nano.Library/blob/master/README.md#nanolibrary)**
* **[Summary](#summary)**
## Summary
Shared building blocks and core implementations used across multiple parts of the Nano ecosystem.
These components provide consistent behavior, reduce duplication, and serve as the foundation for higher-level Nano features used throughout the solution.
-> π Explore the full **[Nano Documentation](https://github.com/Nano-Core/Nano.Library/tree/master/README.md#nanolibrary)**.
+> π Explore the full **[Nano Documentation](https://github.com/Nano-Core/Nano.Library/blob/master/README.md#nanolibrary)**.
diff --git a/Nano.Data.Abstractions/Nano.Data.Abstractions.csproj b/Nano.Data.Abstractions/Nano.Data.Abstractions.csproj
index 9eff0bd6..37a71e6f 100644
--- a/Nano.Data.Abstractions/Nano.Data.Abstractions.csproj
+++ b/Nano.Data.Abstractions/Nano.Data.Abstractions.csproj
@@ -3,7 +3,7 @@
-
+
diff --git a/Nano.Data.Abstractions/README.md b/Nano.Data.Abstractions/README.md
index 00a3ffd9..c3776080 100644
--- a/Nano.Data.Abstractions/README.md
+++ b/Nano.Data.Abstractions/README.md
@@ -10,14 +10,14 @@
***
## Table of Contents
-* **[Home](https://github.com/Nano-Core/Nano.Library/tree/master/README.md#nanolibrary)**
+* **[Home](https://github.com/Nano-Core/Nano.Library/blob/master/README.md#nanolibrary)**
* **[Summary](#summary)**
## Summary
This NuGet provides the core configuration, interfaces, and base abstractions used across all data providers.
This package is not meant to be included directly.
-It serves as a transitive dependency for concrete data providers and is also included in **[Nano Application](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App/README.md#nanoapp)**,
+It serves as a transitive dependency for concrete data providers and is also included in **[Nano Application](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App/README.md#nanoapp)**,
allowing Nano applications to rely on data abstractions rather than specific implementations.
-> π Learn more about **[Nano Data](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md#nanodata)**.
+> π Learn more about **[Nano Data](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md#nanodata)**.
diff --git a/Nano.Data.InMemory/InMemoryProvider.cs b/Nano.Data.InMemory/InMemoryProvider.cs
index 09d95b7b..bba44465 100644
--- a/Nano.Data.InMemory/InMemoryProvider.cs
+++ b/Nano.Data.InMemory/InMemoryProvider.cs
@@ -11,7 +11,7 @@ namespace Nano.Data.InMemory;
///
///
/// This provider uses Entity Framework Core's in-memory database and does not register additional services such as health checks.
-/// Documentation: https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data.InMemory/README.md#nanodatainmemory.
+/// Documentation: https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data.InMemory/README.md#nanodatainmemory.
///
public sealed class InMemoryProvider : IDataProvider
{
diff --git a/Nano.Data.InMemory/Nano.Data.InMemory.csproj b/Nano.Data.InMemory/Nano.Data.InMemory.csproj
index aba0e962..73e679b4 100644
--- a/Nano.Data.InMemory/Nano.Data.InMemory.csproj
+++ b/Nano.Data.InMemory/Nano.Data.InMemory.csproj
@@ -1,7 +1,7 @@
ο»Ώ
-
+
diff --git a/Nano.Data.InMemory/README.md b/Nano.Data.InMemory/README.md
index 7515e2d7..6f843e58 100644
--- a/Nano.Data.InMemory/README.md
+++ b/Nano.Data.InMemory/README.md
@@ -8,7 +8,7 @@
***
## Table of Contents
-* **[Home](https://github.com/Nano-Core/Nano.Library/tree/master/README.md#nanolibrary)**
+* **[Home](https://github.com/Nano-Core/Nano.Library/blob/master/README.md#nanolibrary)**
* **[Summary](#summary)**
* **[Registration](#registration)**
* **[Configuration](#configuration)**
@@ -18,10 +18,10 @@ Data Provider implementation for in-memory data access.
The in-memory data provider doesn't use migrations and there is no need to implement the `BaseDbContextFactory`.
-> π Learn more about **[Nano Data](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md#nanodata)**.
+> π Learn more about **[Nano Data](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md#nanodata)**.
-Try it out yourself using the **[Api.Data.InMemory](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.InMemory)**, or
-**[Console.Data.InMemory](https://github.com/Nano-Core/Nano.Lessons/tree/master/Console.Data.InMemory)** example.
+Try it out yourself using the **[Api.Data.InMemory](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.InMemory)**, or
+**[Console.Data.InMemory](https://github.com/Nano-Core/Nano.Lessons/blob/master/Console.Data.InMemory)** example.
## Registration
Install the **[Nano.Data.InMemory](https://www.nuget.org/packages/Nano.Data.InMemory)** NuGet package.
diff --git a/Nano.Data.MySql/MySqlProvider.cs b/Nano.Data.MySql/MySqlProvider.cs
index 38a1e98d..61871584 100644
--- a/Nano.Data.MySql/MySqlProvider.cs
+++ b/Nano.Data.MySql/MySqlProvider.cs
@@ -13,7 +13,7 @@ namespace Nano.Data.MySql;
///
///
/// Supports retry policies, batching, spatial data via NetTopologySuite, query splitting behavior, and optional health checks.
-/// Documentation: https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data.MySql/README.md#nanodatamysql.
+/// Documentation: https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data.MySql/README.md#nanodatamysql.
///
public sealed class MySqlProvider : IDataProvider
{
diff --git a/Nano.Data.MySql/Nano.Data.MySql.csproj b/Nano.Data.MySql/Nano.Data.MySql.csproj
index 116fedef..f62fe3d6 100644
--- a/Nano.Data.MySql/Nano.Data.MySql.csproj
+++ b/Nano.Data.MySql/Nano.Data.MySql.csproj
@@ -2,8 +2,8 @@
-
-
+
+
diff --git a/Nano.Data.MySql/README.md b/Nano.Data.MySql/README.md
index 43a950c7..b673f705 100644
--- a/Nano.Data.MySql/README.md
+++ b/Nano.Data.MySql/README.md
@@ -8,7 +8,7 @@
***
## Table of Contents
-* **[Home](https://github.com/Nano-Core/Nano.Library/tree/master/README.md#nanolibrary)**
+* **[Home](https://github.com/Nano-Core/Nano.Library/blob/master/README.md#nanolibrary)**
* **[Summary](#summary)**
* **[Registration](#registration)**
* **[Configuration](#configuration)**
@@ -19,11 +19,11 @@
## Summary
Data Provider implementation for MySql data access.
-> π Learn more about **[Nano Data](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md#nanodata)**.
-> π Learn more about **[Nano Azure MySql](https://github.com/Nano-Core/Nano.Kubernetes/tree/master/Nano.Azure.MySql/README.md#nanoazuremysql)**.
+> π Learn more about **[Nano Data](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md#nanodata)**.
+> π Learn more about **[Nano Azure MySql](https://github.com/Nano-Core/Nano.Azure/blob/master/Nano.Azure.MySql/README.md#nanoazuremysql)**.
-Try it out yourself using the **[Api.Data.MySql](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.MySql)**, or
-**[Console.Data.MySql](https://github.com/Nano-Core/Nano.Lessons/tree/master/Console.Data.MySql)** example.
+Try it out yourself using the **[Api.Data.MySql](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.MySql)**, or
+**[Console.Data.MySql](https://github.com/Nano-Core/Nano.Lessons/blob/master/Console.Data.MySql)** example.
## Registration
Install the **[Nano.Data.MySql](https://www.nuget.org/packages/Nano.Data.MySql)** NuGet package.
diff --git a/Nano.Data.PostgreSQL/Nano.Data.PostgreSQL.csproj b/Nano.Data.PostgreSQL/Nano.Data.PostgreSQL.csproj
index 0dea8369..b01e773c 100644
--- a/Nano.Data.PostgreSQL/Nano.Data.PostgreSQL.csproj
+++ b/Nano.Data.PostgreSQL/Nano.Data.PostgreSQL.csproj
@@ -2,8 +2,8 @@
-
-
+
+
diff --git a/Nano.Data.PostgreSQL/PostgreSqlProvider.cs b/Nano.Data.PostgreSQL/PostgreSqlProvider.cs
index e47c080b..4c809a1a 100644
--- a/Nano.Data.PostgreSQL/PostgreSqlProvider.cs
+++ b/Nano.Data.PostgreSQL/PostgreSqlProvider.cs
@@ -13,7 +13,7 @@ namespace Nano.Data.PostgreSQL;
///
///
/// Supports retry policies, batching, spatial data via NetTopologySuite, query splitting behavior, and optional health checks.
-/// Documentation: https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data.PostgreSQL/README.md#nanodatapostgresql.
+/// Documentation: https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data.PostgreSQL/README.md#nanodatapostgresql.
///
public sealed class PostgresSqlProvider : IDataProvider
{
diff --git a/Nano.Data.PostgreSQL/README.md b/Nano.Data.PostgreSQL/README.md
index fb5a0f97..f7aaae4e 100644
--- a/Nano.Data.PostgreSQL/README.md
+++ b/Nano.Data.PostgreSQL/README.md
@@ -8,7 +8,7 @@
***
## Table of Contents
-* **[Home](https://github.com/Nano-Core/Nano.Library/tree/master/README.md#nanolibrary)**
+* **[Home](https://github.com/Nano-Core/Nano.Library/blob/master/README.md#nanolibrary)**
* **[Summary](#summary)**
* **[Registration](#registration)**
* **[Configuration](#configuration)**
@@ -19,11 +19,11 @@
## Summary
Data Provider implementation for PostgreSQL data access.
-> π Learn more about **[Nano Data](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md#nanodata)**.
-> π Learn more about **[Nano Azure PostgreSQL](https://github.com/Nano-Core/Nano.Kubernetes/tree/master/Nano.Azure.PostgreSql/README.md#nanoazurepostgresql)**.
+> π Learn more about **[Nano Data](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md#nanodata)**.
+> π Learn more about **[Nano Azure PostgreSQL](https://github.com/Nano-Core/Nano.Azure/blob/master/Nano.Azure.PostgreSql/README.md#nanoazurepostgresql)**.
-Try it out yourself using the **[Api.Data.PostgreSQL](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.PostgreSQL)**, or
-**[Console.Data.PostgreSQL](https://github.com/Nano-Core/Nano.Lessons/tree/master/Console.Data.PostgreSQL)** example.
+Try it out yourself using the **[Api.Data.PostgreSQL](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.PostgreSQL)**, or
+**[Console.Data.PostgreSQL](https://github.com/Nano-Core/Nano.Lessons/blob/master/Console.Data.PostgreSQL)** example.
## Registration
Install the **[Nano.Data.PostgreSQL](https://www.nuget.org/packages/Nano.Data.PostgreSQL)** NuGet package.
diff --git a/Nano.Data.SqLite/Nano.Data.SqLite.csproj b/Nano.Data.SqLite/Nano.Data.SqLite.csproj
index 491f3255..9af49431 100644
--- a/Nano.Data.SqLite/Nano.Data.SqLite.csproj
+++ b/Nano.Data.SqLite/Nano.Data.SqLite.csproj
@@ -2,7 +2,7 @@
-
+
diff --git a/Nano.Data.SqLite/README.md b/Nano.Data.SqLite/README.md
index 3b7b3985..2bc53c80 100644
--- a/Nano.Data.SqLite/README.md
+++ b/Nano.Data.SqLite/README.md
@@ -8,7 +8,7 @@
***
## Table of Contents
-* **[Home](https://github.com/Nano-Core/Nano.Library/tree/master/README.md#nanolibrary)**
+* **[Home](https://github.com/Nano-Core/Nano.Library/blob/master/README.md#nanolibrary)**
* **[Summary](#summary)**
* **[Registration](#registration)**
* **[Configuration](#configuration)**
@@ -21,10 +21,10 @@ Data Provider implementation for SqLite data access.
> β οΈ SqLite does not natively support spatial types, and `mod_spatialite` is not reliable.
-> π Learn more about **[Nano Data](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md#nanodata)**.
+> π Learn more about **[Nano Data](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md#nanodata)**.
-Try it out yourself using the **[Api.Data.SqLite](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.SqLite)**, or
-**[Console.Data.SqLite](https://github.com/Nano-Core/Nano.Lessons/tree/master/Console.Data.SqLite)** example.
+Try it out yourself using the **[Api.Data.SqLite](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.SqLite)**, or
+**[Console.Data.SqLite](https://github.com/Nano-Core/Nano.Lessons/blob/master/Console.Data.SqLite)** example.
## Registration
Install the **[Nano.Data.SqLite](https://www.nuget.org/packages/Nano.Data.SqLite)** NuGet package.
diff --git a/Nano.Data.SqLite/SqliteProvider.cs b/Nano.Data.SqLite/SqliteProvider.cs
index 48364259..c18bd63d 100644
--- a/Nano.Data.SqLite/SqliteProvider.cs
+++ b/Nano.Data.SqLite/SqliteProvider.cs
@@ -13,7 +13,7 @@ namespace Nano.Data.SqLite;
///
///
/// Intended for local development, lightweight deployments, and embedded database scenarios.
-/// Documentation: https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data.SqLite/README.md#nanodatasqlite
+/// Documentation: https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data.SqLite/README.md#nanodatasqlite
///
public sealed class SqLiteProvider : IDataProvider
{
diff --git a/Nano.Data.SqlServer/Nano.Data.SqlServer.csproj b/Nano.Data.SqlServer/Nano.Data.SqlServer.csproj
index bb39f43d..a47fd2cf 100644
--- a/Nano.Data.SqlServer/Nano.Data.SqlServer.csproj
+++ b/Nano.Data.SqlServer/Nano.Data.SqlServer.csproj
@@ -2,8 +2,8 @@
-
-
+
+
diff --git a/Nano.Data.SqlServer/README.md b/Nano.Data.SqlServer/README.md
index 6fb5f8c7..124d5387 100644
--- a/Nano.Data.SqlServer/README.md
+++ b/Nano.Data.SqlServer/README.md
@@ -8,7 +8,7 @@
***
## Table of Contents
-* **[Home](https://github.com/Nano-Core/Nano.Library/tree/master/README.md#nanolibrary)**
+* **[Home](https://github.com/Nano-Core/Nano.Library/blob/master/README.md#nanolibrary)**
* **[Summary](#summary)**
* **[Registration](#registration)**
* **[Configuration](#configuration)**
@@ -19,11 +19,11 @@
## Summary
Data Provider implementation for Sql Server data access.
-> π Learn more about **[Nano Data](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md#nanodata)**.
-> π Learn more about **[Nano Azure Sql Server](https://github.com/Nano-Core/Nano.Kubernetes/tree/master/Nano.Azure.SqlServer/README.md#nanoazuresqlserver)**.
+> π Learn more about **[Nano Data](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md#nanodata)**.
+> π Learn more about **[Nano Azure Sql Server](https://github.com/Nano-Core/Nano.Azure/blob/master/Nano.Azure.SqlServer/README.md#nanoazuresqlserver)**.
-Try it out yourself using the **[Api.Data.SqlServer](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.SqlServer)**, or
-**[Console.Data.SqlServer](https://github.com/Nano-Core/Nano.Lessons/tree/master/Console.Data.SqlServer)** example.
+Try it out yourself using the **[Api.Data.SqlServer](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.SqlServer)**, or
+**[Console.Data.SqlServer](https://github.com/Nano-Core/Nano.Lessons/blob/master/Console.Data.SqlServer)** example.
## Registration
Install the **[Nano.Data.SqlServer](https://www.nuget.org/packages/Nano.Data.SqlServer)** NuGet package.
diff --git a/Nano.Data.SqlServer/SqlServerProvider.cs b/Nano.Data.SqlServer/SqlServerProvider.cs
index 39c5786d..386f6e75 100644
--- a/Nano.Data.SqlServer/SqlServerProvider.cs
+++ b/Nano.Data.SqlServer/SqlServerProvider.cs
@@ -13,7 +13,7 @@ namespace Nano.Data.SqlServer;
///
///
/// Supports retry policies, batching, spatial data via NetTopologySuite, query splitting behavior, and optional health checks.
-/// Documentation: https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data.SqlServer/README.md#nanodatasqlserver.
+/// Documentation: https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data.SqlServer/README.md#nanodatasqlserver.
///
public sealed class SqlServerProvider : IDataProvider
{
diff --git a/Nano.Data/Abstractions/IDataProvider.cs b/Nano.Data/Abstractions/IDataProvider.cs
index ab539018..efe103d7 100644
--- a/Nano.Data/Abstractions/IDataProvider.cs
+++ b/Nano.Data/Abstractions/IDataProvider.cs
@@ -7,7 +7,7 @@ namespace Nano.Data.Abstractions;
///
/// Defines a data provider used to configure the application's data access layer.
///
-/// Documentation: https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md#nanodata
+/// Documentation: https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md#nanodata
public interface IDataProvider
{
///
diff --git a/Nano.Data/Nano.Data.csproj b/Nano.Data/Nano.Data.csproj
index 452f5750..9d1937b1 100644
--- a/Nano.Data/Nano.Data.csproj
+++ b/Nano.Data/Nano.Data.csproj
@@ -2,14 +2,14 @@
-
-
-
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
+
+
+
diff --git a/Nano.Data/README.md b/Nano.Data/README.md
index 7758dac0..08a6f020 100644
--- a/Nano.Data/README.md
+++ b/Nano.Data/README.md
@@ -10,7 +10,7 @@
***
## Table of Contents
-* **[Home](https://github.com/Nano-Core/Nano.Library/tree/master/README.md#nanolibrary#nanolibrary)**
+* **[Home](https://github.com/Nano-Core/Nano.Library/blob/master/README.md#nanolibrary#nanolibrary)**
* **[Summary](#summary)**
* **[Registration](#registration)**
* **[Variables And Secrets](#variables-and-secrets)**
@@ -135,7 +135,7 @@ The `Data` section in the configuration defines the data provider and related se
}
```
-> π Learn more about **[Application Configuration](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App/README.md#configuration)** here.
+> π Learn more about **[Application Configuration](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App/README.md#configuration)** here.
## Connection Pool
Nano supports optional connection pooling for the underlying Entity Framework data provider. When enabled, database contexts are reused from a pool, which can improve performance
@@ -255,7 +255,7 @@ functionality. See **[Repositories](#repositories)** for more details.
Nano also provides a public `SecurePasswordGenerator` class for creating strong, secure passwords.
-Try it out yourself using the **[Api.Data.Identity](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.Identity)**.
+Try it out yourself using the **[Api.Data.Identity](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.Identity)**.
## Health Checks
When health checks are enabled in the data configuration, Nano automatically registers a health check for the configured data provider.
@@ -296,11 +296,11 @@ Once implemented, the provider can be added to the application during startup co
The following data providers are currently supported in Nano.
-* **[Nano.Data.InMemory](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data.InMemory/README.md#nanodatainmemory)**
-* **[Nano.Data.MySql](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data.MySql/README.md#nanodatamysql)**
-* **[Nano.Data.PostgreSQL](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data.PostgreSQL/README.md#nanodatapostgresql)**
-* **[Nano.Data.SqLite](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data.SqLite/README.md#nanodatasqlite)**
-* **[Nano.Data.SqlServer](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data.SqlServer/README.md#nanodatasqlserver)**
+* **[Nano.Data.InMemory](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data.InMemory/README.md#nanodatainmemory)**
+* **[Nano.Data.MySql](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data.MySql/README.md#nanodatamysql)**
+* **[Nano.Data.PostgreSQL](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data.PostgreSQL/README.md#nanodatapostgresql)**
+* **[Nano.Data.SqLite](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data.SqLite/README.md#nanodatasqlite)**
+* **[Nano.Data.SqlServer](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data.SqlServer/README.md#nanodatasqlserver)**
## Data Context
Nano provides built-in management for the `DbContext` while still letting you use it as you normally would.
@@ -363,8 +363,8 @@ must implement the corresponding interfaces: `IEntityReadOnly`, `IEntityWritable
> π‘ For simplicity and maintainability, it is recommended to derive entity models from `BaseEntity` or one of the specific base classes rather than
implementing the interfaces directly.
-Try it out yourself using the **[Api.Data.Mysql](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.Mysql)** or
-**[Console.Data.Mysql](https://github.com/Nano-Core/Nano.Lessons/tree/master/Console.Data.Mysql)** examples. Similar examples are available for other data providers as well.
+Try it out yourself using the **[Api.Data.Mysql](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.MySql)** or
+**[Console.Data.Mysql](https://github.com/Nano-Core/Nano.Lessons/blob/master/Console.Data.MySql)** examples. Similar examples are available for other data providers as well.
Nano also contains another important base entity model. The `BaseEntityUser` and `BaseEntityUser`. When **[Identity](#identity)** has been configured for an application,
the entity user base classes defines the user model of the application and are having `IdentityUser` associated. The base class itself derives from `BaseEntity`, and behaves in the
@@ -406,7 +406,7 @@ Generally, you do not need to interact with the identity models directly. Use th
the identity models are available through the **[Data Context](#data-context)** like any other entity. Bypassing the `IIdentityRepository` is not recommended, as it may
unintentionally bypass critical identity logic.
-Try it out yourself using the **[Api.Data.Identity](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.Identity)** example.
+Try it out yourself using the **[Api.Data.Identity](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.Identity)** example.
Nano also supports defining views in the entity model. The `BaseEntityView` entity class can be used to define a model for a SQL view.
@@ -417,10 +417,10 @@ public class MyEntityView : BaseEntityView
}
```
-Try it out yourself using the **[Api.Data.MySql.Views](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.MySql.Views)** example.
+Try it out yourself using the **[Api.Data.MySql.Views](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.MySql.Views)** example.
Spatial `Geometry` types from `NetToplogySuite` is also supported. Try it out yourself using the
-**[Api.Data.MySql.Spatial](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.MySql.Spatial)** example.
+**[Api.Data.MySql.Spatial](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.MySql.Spatial)** example.
## Data Mappings
Each data model in your application should have a corresponding non-generic data mapping with a parameterless constructor. Data mappings define how your entities are configured
@@ -474,14 +474,14 @@ public class MyEntityViewMapping : BaseEntityViewMapping
}
```
-Try it out views yourself using the **[Api.Data.MySql.Views](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.MySql.Views)** example.
+Try it out views yourself using the **[Api.Data.MySql.Views](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.MySql.Views)** example.
Nano automatically updates all unique index mappings to include the `IsDeleted` property. This ensures that soft-deleted entities can coexist without violating
uniqueness constraints.
Mapping of spatial types varies between data providers. Refer to your provider's spatial documentation for details.
-Explore spatial and other advanced mappings using the **[Api.Data.MySql.Mappings](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.MySql.Mappings)** example.
+Explore spatial and other advanced mappings using the **[Api.Data.MySql.Mappings](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.MySql.Mappings)** example.
## Migrations
Migrations in Nano work the same way as standard Entity Framework migrations.
@@ -521,8 +521,8 @@ dotnet ef database update `
> β οΈ Entity Framework does not handle views, stored procedures, or functions in migrations, they must be added or modified manually to migrations.
-To manage views or stored procedures in migrations take a look at the **[Api.Data.MySql.Views](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.MySql.Views)** or
-**[Api.Data.MySql.StoredProcedures](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.MySql.StoredProcedures)** example for best practices.
+To manage views or stored procedures in migrations take a look at the **[Api.Data.MySql.Views](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.MySql.Views)** or
+**[Api.Data.MySql.StoredProcedures](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.MySql.StoredProcedures)** example for best practices.
> π Learn more about **[EF Migrations](https://learn.microsoft.com/en-us/ef/core/managing-schemas/migrations/?tabs=dotnet-core-cli)**.
@@ -591,8 +591,8 @@ One of the most useful parameters is `includeDepth`, which overrides the globall
are applied in a query. This allows you to map complex entity models with related entities, while also controlling how much of the entity graph is loaded. Sometimes you may want
only the plain entity, while other times you may need the full inclusion tree.
-Try it out yourself using the **[Api.Data.Mysql](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.Mysql)** or
-**[Console.Data.Mysql](https://github.com/Nano-Core/Nano.Lessons/tree/master/Console.Data.Mysql)** examples. Similar examples are available for other data providers as well.
+Try it out yourself using the **[Api.Data.Mysql](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.MySql)** or
+**[Console.Data.Mysql](https://github.com/Nano-Core/Nano.Lessons/blob/master/Console.Data.MySql)** examples. Similar examples are available for other data providers as well.
Nano also provides a dedicated repository for managing entity user models, the `IIdentityRepository` and `IIdentityRepository`. These repositories expose common identity
operations such as login, signup, email changes, management of roles and claims, etc. Internally, the repository encapsulates functionality from `UserManager` and
@@ -679,7 +679,7 @@ identity logic through a single, consistent repository.
| `AssignOrReplaceRoleClaimAsync` | Role Claims | roleId, assignOrReplaceClaim | Assigns a claim to a role or replaces it if it already exists. |
| `RemoveRoleClaimAsync` | Role Claims | roleId, removeClaim | Removes a claim from a role. |
-Try it out yourself using the **[Api.Data.Identity](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.Mysql)** example.
+Try it out yourself using the **[Api.Data.Identity](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.Identity)** example.
## Autosave
The repository can be configured for autosave. When enabled, all methods that modify data will automatically persist changes to the database. No need to call
@@ -688,7 +688,7 @@ multiple individual add or update calls.
If you need more fine-grained control over when changes are committed, you can disable `UseAutoSave` in the repository configuration.
-Try it out yourself using the **[Api.Data.Repository.Autosave](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.Repository.Autosave)**.
+Try it out yourself using the **[Api.Data.Repository.Autosave](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.Repository.Autosave)**.
## Cache
Currently, Nano does not support data caching.
@@ -712,7 +712,7 @@ For large collections, `SplitQuery` is recommended. If no `QuerySplitBehavior` i
This feature is particularly useful because it allows you to build full entity graphs rather than retrieving single entities. When you need only the base entity, the graph inclusion
can easily be overridden through the various `IRepository` methods.
-Try it out yourself using the **[Api.Data.Repository.Includes](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.Repository.Includes)**.
+Try it out yourself using the **[Api.Data.Repository.Includes](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.Repository.Includes)**.
## Audit
Audit logging is enabled by default in Nano. To enable auditing for an entity, the entity model must implement the `IEntityAuditable` interface. When implemented, the entity and all
@@ -735,7 +735,7 @@ soft-deleted entities, the audit reflects the soft-delete state rather than a re
The audit implementation is based on the **[EntityFramework Plus](https://github.com/zzzprojects/EntityFramework-Plus)** project.
-Try it out yourself using the **[Api.Data.Audit](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.Audit)**.
+Try it out yourself using the **[Api.Data.Audit](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.Audit)**.
## Soft Delete
If you want a model to use soft-delete, simply implement the `IEntitySoftDeletable` interface.
@@ -751,7 +751,7 @@ Unlike regular deletes, soft-deleting entities does not support cascading delete
When dealing with soft-deleted entities together with unique indexes, conflicts can arise if one or more deleted entities have duplicate unique values. Nano automatically
adjusts unique indexes by appending the `IsDeleted` property, with the exception of the primary key.
-Try it out yourself using the **[Api.Data.SoftDelete](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.SoftDelete)**.
+Try it out yourself using the **[Api.Data.SoftDelete](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.SoftDelete)**.
## Lazy Loading
Load related data from the database only when it is first accessed, not when the parent entity is retrieved. This can reduce unnecessary queries but may cause extra database
@@ -763,7 +763,7 @@ When lazy loading is enabled in the configuration, navigation properties will be
[Include Annotation](#include-annotation). Normally, these properties should already be loaded, but if you retrieve entity models without including them, the serializer
will trigger lazy-loading to fetch the missing data.
-Try it out yourself using the **[Api.Data.LazyLoading](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.LazyLoading)**.
+Try it out yourself using the **[Api.Data.LazyLoading](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.LazyLoading)**.
## Triggers
Triggers in Nano are logic-based events that occur before or after an add, update, or delete operation, and are not classic SQL triggers. These triggers are executed at the
@@ -807,7 +807,7 @@ for tasks other than altering the entity itself.
Triggers are best used for small, self-contained tasks, such as updating an `UpdatedAt` property in an `OnUpdating` trigger or calculating an aggregate value based on
entity properties. More complex logic should be handled in dedicated services within your application.
-Try it out yourself using the **[Api.Data.Triggers](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.Triggers)**.
+Try it out yourself using the **[Api.Data.Triggers](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.Triggers)**.
## Entity Events
In Nano, entity events provide a straightforward way to synchronize data changes across applications. They enable automatic propagation of entity state changes based on navigation properties and
@@ -821,7 +821,7 @@ create, update, or delete operations to the local model.
This approach provides a simple and consistent mechanism for maintaining data synchronization across services, reducing integration complexity while preserving clear ownership boundaries between applications.
-> β οΈ Entity Events require **[Eventing](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Eventing/README.md#nanoeventing)** to be configured in the application.
+> β οΈ Entity Events require **[Eventing](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Eventing/README.md#nanoeventing)** to be configured in the application.
Only entities implementing `IEntityIdentity` are eligible for participation in entity eventing. The attribute allows a configurable list of publish properties, which determines the data included
in the generated event payload. For entities deriving from `BaseEntity`, the `CreatedAt` property is automatically included to ensure consistent timestamp synchronization between publishers and subscribers.
@@ -869,4 +869,4 @@ public class MyEntity : DefaultEntity
publish properties such as `IdentityUser.Email` or `IdentityUser.Phone`, allowing downstream services like email or SMS systems to subscribe and receive all required data upfront.
This enables each service to independently fulfill its responsibility without additional lookups or coupling to the source system.
-Try it out yourself using the **[Api.Data.EntityEvents](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Data.EntityEvents)**.
+Try it out yourself using the **[Api.Data.EntityEvents](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Data.EntityEvents)**.
diff --git a/Nano.Eventing.Abstractions/README.md b/Nano.Eventing.Abstractions/README.md
index 4c291e34..d509f649 100644
--- a/Nano.Eventing.Abstractions/README.md
+++ b/Nano.Eventing.Abstractions/README.md
@@ -10,14 +10,14 @@
***
## Table of Contents
-* **[Home](https://github.com/Nano-Core/Nano.Library/tree/master/README.md#nanolibrary)**
+* **[Home](https://github.com/Nano-Core/Nano.Library/blob/master/README.md#nanolibrary)**
* **[Summary](#summary)**
## Summary
This NuGet provides the core configuration, interfaces, and base abstractions used across all eventing providers.
This package is not meant to be included directly.
-It serves as a transitive dependency for concrete eventing providers and is also included in **[Nano Application](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App/README.md#nanoapp),
+It serves as a transitive dependency for concrete eventing providers and is also included in **[Nano Application](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App/README.md#nanoapp),
allowing Nano applications to rely on eventing abstractions rather than specific implementations.
-> π Learn more about **[Nano Eventing](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Eventing/README.md#nanoeventing)**.
+> π Learn more about **[Nano Eventing](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Eventing/README.md#nanoeventing)**.
diff --git a/Nano.Eventing.RabbitMq/README.md b/Nano.Eventing.RabbitMq/README.md
index fc7f4ddf..fc28d873 100644
--- a/Nano.Eventing.RabbitMq/README.md
+++ b/Nano.Eventing.RabbitMq/README.md
@@ -8,21 +8,21 @@
***
## Table of Contents
-* **[Home](https://github.com/Nano-Core/Nano.Library/tree/master/README.md#nanolibrary)**
+* **[Home](https://github.com/Nano-Core/Nano.Library/blob/master/README.md#nanolibrary)**
* **[Summary](#summary)**
* **[Registration](#registration)**
* **[Configuration](#configuration)**
* **[Docker Compose](#docker-compose)**
-* **[Kuberentes](#kuberentes)**
+* **[Kubernetes](#kubernetes)**
## Summary
Eventing Provider implementation for RabbitMq.
-> π Learn more about **[Nano Eventing](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Eventing/README.md#nanoeventing)**.
-> π Learn more about **[Nano Kubernetes RabbitMq](https://github.com/Nano-Core/Nano.Kubernetes/tree/master/Nano.Kubernetes.RabbitMq)**.
+> π Learn more about **[Nano Eventing](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Eventing/README.md#nanoeventing)**.
+> π Learn more about **[Nano Kubernetes RabbitMq](https://github.com/Nano-Core/Nano.Azure.Kubernetes/blob/master/Nano.Azure.Kubernetes.RabbitMQ/README.md#nanoazurekubernetesrabbitmq)**.
-Try it out yourself using the **[Api.Eventing.RabbitMq](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Eventing.RabbitMq)** or
-**[Console.Eventing.RabbitMq](https://github.com/Nano-Core/Nano.Lessons/tree/master/Console.Eventing.RabbitMq)** example.
+Try it out yourself using the **[Api.Eventing.RabbitMq](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Eventing.RabbitMq)** or
+**[Console.Eventing.RabbitMq](https://github.com/Nano-Core/Nano.Lessons/blob/master/Console.Eventing.RabbitMq)** example.
## Registration
Install the **[Nano.Eventing.RabbitMq](https://www.nuget.org/packages/Nano.Eventing.RabbitMq/README.md#nanoeventingrabbitmq)** NuGet package.
@@ -123,7 +123,7 @@ spec:
key: password
```
-You also need to map the `rabbitmq` secret that is created alongside the **[Nano Azure Kuberenetes Eventing](https://github.com/Nano-Core/Nano.Azure.Kubernetes/tree/master/Nano.Azure.Kubernetes.RabbitMQ/README.md#nanoazurekubernetesrabbitmq)**
+You also need to map the `rabbitmq` secret that is created alongside the **[Nano Azure Kuberenetes Eventing](https://github.com/Nano-Core/Nano.Azure.Kubernetes/blob/master/Nano.Azure.Kubernetes.RabbitMQ/README.md#nanoazurekubernetesrabbitmq)**
in the `deployment.yaml` or `cronjob.yaml` for eventing authentication.
> β οΈ The `rabbitmq` secret will be reused for all applications using RabbitMQ as eventing provider.
diff --git a/Nano.Eventing.RabbitMq/RabbitMqProvider.cs b/Nano.Eventing.RabbitMq/RabbitMqProvider.cs
index 5a270383..f047a103 100644
--- a/Nano.Eventing.RabbitMq/RabbitMqProvider.cs
+++ b/Nano.Eventing.RabbitMq/RabbitMqProvider.cs
@@ -18,7 +18,7 @@ namespace Nano.Eventing.RabbitMq;
///
///
///
-/// Documentation: https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Eventing.RabbitMq/README.md#nanoeventingrabbitmq
+/// Documentation: https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Eventing.RabbitMq/README.md#nanoeventingrabbitmq
public sealed class RabbitMqProvider : IEventingProvider
{
///
diff --git a/Nano.Eventing/Abstractions/IEventingProvider.cs b/Nano.Eventing/Abstractions/IEventingProvider.cs
index e75f0e8a..ef0b037d 100644
--- a/Nano.Eventing/Abstractions/IEventingProvider.cs
+++ b/Nano.Eventing/Abstractions/IEventingProvider.cs
@@ -7,7 +7,7 @@ namespace Nano.Eventing.Abstractions;
/// Defines a generic interface for an eventing provider in the Nano application.
/// Eventing providers are responsible for delivering and handling events, and this interface allows different '
/// implementations (e.g., RabbitMQ, Azure Service Bus, Kafka, etc.).
-/// Documentation: https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Eventing/README.md#nanoeventing
+/// Documentation: https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Eventing/README.md#nanoeventing
///
public interface IEventingProvider
{
diff --git a/Nano.Eventing/README.md b/Nano.Eventing/README.md
index 11068ef5..0c8f575d 100644
--- a/Nano.Eventing/README.md
+++ b/Nano.Eventing/README.md
@@ -10,7 +10,7 @@
***
## Table of Contents
-* **[Home](https://github.com/Nano-Core/Nano.Library/tree/master/README.md#nanolibrary)**
+* **[Home](https://github.com/Nano-Core/Nano.Library/blob/master/README.md#nanolibrary)**
* **[Summary](#summary)**
* **[Registration](#registration)**
* **[Configuration](#configuration)**
@@ -83,7 +83,7 @@ The ```Eventing``` section in the configuration defines the eventing provider an
}
```
-> π Learn more about **[Application Configuration](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App/README.md#configuration)** here.
+> π Learn more about **[Application Configuration](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App/README.md#configuration)** here.
## Health Checks
When health checks are enabled in the eventing configuration, Nano automatically registers a health check for the configured eventing provider.
@@ -128,7 +128,7 @@ services
```
The following eventing providers are currently supported in Nano:
-* **[Nano.Eventing.RabbitMq](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Eventing.RabbitMq/README.md#nanoeventingrabbitmq)**
+* **[Nano.Eventing.RabbitMq](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Eventing.RabbitMq/README.md#nanoeventingrabbitmq)**
Additional providers can be implemented by following the same pattern, allowing you to extend Nanoβs eventing system to any messaging broker of your choice.
diff --git a/Nano.Logging.Abstractions/Nano.Logging.Abstractions.csproj b/Nano.Logging.Abstractions/Nano.Logging.Abstractions.csproj
index 92a1b11b..546f9a09 100644
--- a/Nano.Logging.Abstractions/Nano.Logging.Abstractions.csproj
+++ b/Nano.Logging.Abstractions/Nano.Logging.Abstractions.csproj
@@ -1,7 +1,7 @@
ο»Ώ
-
+
diff --git a/Nano.Logging.Abstractions/README.md b/Nano.Logging.Abstractions/README.md
index 170ca647..6cb3e58e 100644
--- a/Nano.Logging.Abstractions/README.md
+++ b/Nano.Logging.Abstractions/README.md
@@ -10,14 +10,14 @@
***
## Table of Contents
-* **[Home](https://github.com/Nano-Core/Nano.Library/tree/master/README.md#nanolibrary)**
+* **[Home](https://github.com/Nano-Core/Nano.Library/blob/master/README.md#nanolibrary)**
* **[Summary](#summary)**
## Summary
This NuGet provides the core configuration, interfaces, and base abstractions used across all logging providers.
This package is not meant to be included directly.
-It serves as a transitive dependency for concrete logging providers and is also included in **[Nano Application](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App/README.md#nanoapp)**,
+It serves as a transitive dependency for concrete logging providers and is also included in **[Nano Application](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App/README.md#nanoapp)**,
allowing Nano applications to rely on logging abstractions rather than specific implementations.
-> π Learn more about **[Nano Logging](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Logging/README.md#nanologging)**.
+> π Learn more about **[Nano Logging](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Logging/README.md#nanologging)**.
diff --git a/Nano.Logging.Log4Net/Log4NetProvider.cs b/Nano.Logging.Log4Net/Log4NetProvider.cs
index 958a57c0..761be247 100644
--- a/Nano.Logging.Log4Net/Log4NetProvider.cs
+++ b/Nano.Logging.Log4Net/Log4NetProvider.cs
@@ -14,7 +14,7 @@ namespace Nano.Logging.Log4Net;
///
/// A logging provider that configures log4net as the application's logging framework.
///
-/// Documentation: https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Logging.Log4Net/README.md#nanologginglog4net
+/// Documentation: https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Logging.Log4Net/README.md#nanologginglog4net
public sealed class Log4NetProvider : ILoggingProvider
{
///
diff --git a/Nano.Logging.Log4Net/README.md b/Nano.Logging.Log4Net/README.md
index 03ffa757..a6077a36 100644
--- a/Nano.Logging.Log4Net/README.md
+++ b/Nano.Logging.Log4Net/README.md
@@ -8,7 +8,7 @@
***
## Table of Contents
-* **[Home](https://github.com/Nano-Core/Nano.Library/tree/master/README.md#nanolibrary)**
+* **[Home](https://github.com/Nano-Core/Nano.Library/blob/master/README.md#nanolibrary)**
* **[Summary](#summary)**
* **[Registration](#registration)**
@@ -20,10 +20,10 @@ The provider is preconfigured to write log output to the console using a concise
%utcdate{dd-MM-yyyy HH:mm:ss.ffffff} [%level{3}] %message%newline%exception
```
-> π Learn more about **[Nano Logging](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Logging/README.md#nanologging)**.
+> π Learn more about **[Nano Logging](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Logging/README.md#nanologging)**.
-Try it out yourself using the **[Api.Logging.Log4Net](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Logging.Log4Net/README.md#nanologginglog4net)** or
-**[Console.Logging.Log4Net](https://github.com/Nano-Core/Nano.Lessons/tree/master/Console.Logging.Log4Net)** example.
+Try it out yourself using the **[Api.Logging.Log4Net](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Logging.Log4Net)** or
+**[Console.Logging.Log4Net](https://github.com/Nano-Core/Nano.Lessons/blob/master/Console.Logging.Log4Net)** example.
## Registration
Install the **[Nano.Logging.Log4Net](https://www.nuget.org/packages/Nano.Logging.Log4Net)** NuGet package.
diff --git a/Nano.Logging.Microsoft/MicrosoftProvider.cs b/Nano.Logging.Microsoft/MicrosoftProvider.cs
index 5a01cca6..2078ef24 100644
--- a/Nano.Logging.Microsoft/MicrosoftProvider.cs
+++ b/Nano.Logging.Microsoft/MicrosoftProvider.cs
@@ -11,7 +11,7 @@ namespace Nano.Logging.Microsoft;
///
/// A logging provider that configures the built-in Microsoft.Extensions.Logging framework.
///
-/// Documentation: https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Logging.Microsoft/README.md#nanologgingmicrosoft
+/// Documentation: https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Logging.Microsoft/README.md#nanologgingmicrosoft
public sealed class MicrosoftProvider : ILoggingProvider
{
///
diff --git a/Nano.Logging.Microsoft/Nano.Logging.Microsoft.csproj b/Nano.Logging.Microsoft/Nano.Logging.Microsoft.csproj
index 18f17b9b..7e8bbc1c 100644
--- a/Nano.Logging.Microsoft/Nano.Logging.Microsoft.csproj
+++ b/Nano.Logging.Microsoft/Nano.Logging.Microsoft.csproj
@@ -1,7 +1,7 @@
ο»Ώ
-
+
diff --git a/Nano.Logging.Microsoft/README.md b/Nano.Logging.Microsoft/README.md
index ac6cbf2b..db4059da 100644
--- a/Nano.Logging.Microsoft/README.md
+++ b/Nano.Logging.Microsoft/README.md
@@ -8,7 +8,7 @@
***
## Table of Contents
-* **[Home](https://github.com/Nano-Core/Nano.Library/tree/master/README.md#nanolibrary)**
+* **[Home](https://github.com/Nano-Core/Nano.Library/blob/master/README.md#nanolibrary)**
* **[Summary](#summary)**
* **[Registration](#registration)**
@@ -20,10 +20,10 @@ The provider is preconfigured to write log output to the console using a concise
{Timestamp:dd-MM-yyyy HH:mm:ss.ffffff} [{Level:u3}] {Message}{NewLine}{Exception}
```
-> π Learn more about **[Nano Logging](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Logging/README.md#nanologging)**.
+> π Learn more about **[Nano Logging](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Logging/README.md#nanologging)**.
-Try it out yourself using the **[Api.Logging.Microsoft](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Logging.Microsoft)** or
-**[Console.Logging.Microsoft](https://github.com/Nano-Core/Nano.Lessons/tree/master/Console.Logging.Microsoft)** example.
+Try it out yourself using the **[Api.Logging.Microsoft](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Logging.Microsoft)** or
+**[Console.Logging.Microsoft](https://github.com/Nano-Core/Nano.Lessons/blob/master/Console.Logging.Microsoft)** example.
## Registration
Install the **[Nano.Logging.Microsoft](https://www.nuget.org/packages/Nano.Logging.Microsoft)** NuGet package.
diff --git a/Nano.Logging.NLog/NLogProvider.cs b/Nano.Logging.NLog/NLogProvider.cs
index 00a3dbc0..fc3d8dff 100644
--- a/Nano.Logging.NLog/NLogProvider.cs
+++ b/Nano.Logging.NLog/NLogProvider.cs
@@ -13,7 +13,7 @@ namespace Nano.Logging.NLog;
///
/// A logging provider that configures NLog as the application's logging framework.
///
-/// Documentation: https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Logging.NLog/README.md#nanologgingnlog.
+/// Documentation: https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Logging.NLog/README.md#nanologgingnlog.
public sealed class NLogProvider : ILoggingProvider
{
///
diff --git a/Nano.Logging.NLog/Nano.Logging.NLog.csproj b/Nano.Logging.NLog/Nano.Logging.NLog.csproj
index 35e7761d..c0136a5b 100644
--- a/Nano.Logging.NLog/Nano.Logging.NLog.csproj
+++ b/Nano.Logging.NLog/Nano.Logging.NLog.csproj
@@ -1,9 +1,9 @@
ο»Ώ
-
-
-
+
+
+
diff --git a/Nano.Logging.NLog/README.md b/Nano.Logging.NLog/README.md
index 9e455428..f9a45cf6 100644
--- a/Nano.Logging.NLog/README.md
+++ b/Nano.Logging.NLog/README.md
@@ -8,7 +8,7 @@
***
## Table of Contents
-* **[Home](https://github.com/Nano-Core/Nano.Library/tree/master/README.md#nanolibrary)**
+* **[Home](https://github.com/Nano-Core/Nano.Library/blob/master/README.md#nanolibrary)**
* **[Summary](#summary)**
* **[Registration](#registration)**
@@ -20,10 +20,10 @@ The provider is preconfigured to write log output to the console using a concise
${date:format=dd-MM-yyyy HH\\:mm\\:ss.ffffff} [${level:uppercase=true:truncate=3}] ${message}${onexception:${newline}${exception:format=toString}}
```
-> π Learn more about **[Nano Logging](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Logging/README.md#nanologging)**.
+> π Learn more about **[Nano Logging](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Logging/README.md#nanologging)**.
-Try it out yourself using the **[Api.Logging.NLog](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Logging.NLog)** or
-**[Console.Logging.NLog](https://github.com/Nano-Core/Nano.Lessons/tree/master/Console.Logging.NLog)** example.
+Try it out yourself using the **[Api.Logging.NLog](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Logging.NLog)** or
+**[Console.Logging.NLog](https://github.com/Nano-Core/Nano.Lessons/blob/master/Console.Logging.NLog)** example.
## Registration
Install the **[Nano.Logging.NLog](https://www.nuget.org/packages/Nano.Logging.NLog)** NuGet package.
diff --git a/Nano.Logging.Serilog/Nano.Logging.Serilog.csproj b/Nano.Logging.Serilog/Nano.Logging.Serilog.csproj
index 958d63a1..b2822feb 100644
--- a/Nano.Logging.Serilog/Nano.Logging.Serilog.csproj
+++ b/Nano.Logging.Serilog/Nano.Logging.Serilog.csproj
@@ -1,7 +1,7 @@
ο»Ώ
-
+
diff --git a/Nano.Logging.Serilog/README.md b/Nano.Logging.Serilog/README.md
index 2d03adef..faaf75d6 100644
--- a/Nano.Logging.Serilog/README.md
+++ b/Nano.Logging.Serilog/README.md
@@ -8,7 +8,7 @@
***
## Table of Contents
-* **[Home](https://github.com/Nano-Core/Nano.Library/tree/master/README.md#nanolibrary)**
+* **[Home](https://github.com/Nano-Core/Nano.Library/blob/master/README.md#nanolibrary)**
* **[Summary](#summary)**
* **[Registration](#registration)**
@@ -20,10 +20,10 @@ The provider is preconfigured to write log output to the console using a concise
{Timestamp:dd-MM-yyyy HH:mm:ss.ffffff} [{Level:u3}] {Message}{NewLine}{Exception}
```
-> π Learn more about **[Nano Logging](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Logging/README.md#nanologging)**.
+> π Learn more about **[Nano Logging](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Logging/README.md#nanologging)**.
-Try it out yourself using the **[Api.Logging.Serilog](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Logging.Serilog)** or
-**[Console.Logging.Serilog](https://github.com/Nano-Core/Nano.Lessons/tree/master/Console.Logging.Serilog)** example.
+Try it out yourself using the **[Api.Logging.Serilog](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Logging.Serilog)** or
+**[Console.Logging.Serilog](https://github.com/Nano-Core/Nano.Lessons/blob/master/Console.Logging.Serilog)** example.
## Registration
Install the **[Nano.Logging.Serilog](https://www.nuget.org/packages/Nano.Logging.Serilog)** NuGet package.
diff --git a/Nano.Logging.Serilog/SerilogProvider.cs b/Nano.Logging.Serilog/SerilogProvider.cs
index 8c01061f..d922f586 100644
--- a/Nano.Logging.Serilog/SerilogProvider.cs
+++ b/Nano.Logging.Serilog/SerilogProvider.cs
@@ -10,7 +10,7 @@ namespace Nano.Logging.Serilog;
///
/// A logging provider that configures Serilog as the application's logging framework.
///
-/// Documentation: https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Logging.Serilog/README.md#nanologgingserilog
+/// Documentation: https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Logging.Serilog/README.md#nanologgingserilog
public sealed class SerilogProvider : ILoggingProvider
{
///
diff --git a/Nano.Logging/Abstractions/ILoggingProvider.cs b/Nano.Logging/Abstractions/ILoggingProvider.cs
index 075c47ac..5680eb48 100644
--- a/Nano.Logging/Abstractions/ILoggingProvider.cs
+++ b/Nano.Logging/Abstractions/ILoggingProvider.cs
@@ -7,7 +7,7 @@ namespace Nano.Logging.Abstractions;
/// Represents a logging provider for the application.
/// Implementations define how logging is configured and integrated into the service collection.
///
-/// Documentation: https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Logging
+/// Documentation: https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Logging
public interface ILoggingProvider
{
///
diff --git a/Nano.Logging/Extensions/ServiceCollectionExtensions.cs b/Nano.Logging/Extensions/ServiceCollectionExtensions.cs
index f93d488a..ada8a091 100644
--- a/Nano.Logging/Extensions/ServiceCollectionExtensions.cs
+++ b/Nano.Logging/Extensions/ServiceCollectionExtensions.cs
@@ -19,7 +19,7 @@ public static class ServiceCollectionExtensions
/// The type of the logging provider to register. Must implement and have a parameterless constructor.
/// The to add the logging provider to.
/// The same instance for chaining.
- /// Documentation: https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Logging/README.md#nanologging.
+ /// Documentation: https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Logging/README.md#nanologging.
/// Thrown if is null.
public static IServiceCollection AddNanoLogging(this IServiceCollection services)
where TProvider : ILoggingProvider
diff --git a/Nano.Logging/Nano.Logging.csproj b/Nano.Logging/Nano.Logging.csproj
index 626c7246..61d2d887 100644
--- a/Nano.Logging/Nano.Logging.csproj
+++ b/Nano.Logging/Nano.Logging.csproj
@@ -1,7 +1,7 @@
ο»Ώ
-
+
diff --git a/Nano.Logging/README.md b/Nano.Logging/README.md
index 211d4dbf..2652a57d 100644
--- a/Nano.Logging/README.md
+++ b/Nano.Logging/README.md
@@ -10,7 +10,7 @@
***
## Table of Contents
-* **[Home](https://github.com/Nano-Core/Nano.Library/tree/master/README.md#nanolibrary)**
+* **[Home](https://github.com/Nano-Core/Nano.Library/blob/master/README.md#nanolibrary)**
* **[Summary](#summary)**
* **[Registration](#registration)**
* **[Configuration](#configuration)**
@@ -68,7 +68,7 @@ The ```Logging``` section in the configuration defines the logging provider and
}
```
-> π Learn more about **[Application Configuration](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App/README.md#configuration)** here.
+> π Learn more about **[Application Configuration](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App/README.md#configuration)** here.
## Logging Providers
Nano provides several logging providers, so usually there is no need to implement a custom provider for your application.
@@ -81,7 +81,7 @@ and then register your provider with the application using `.AddNanoLogging π Learn more about **[Nano Storage](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Storage/README.md#nanostorage)**.
+> π Learn more about **[Nano Storage](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Storage/README.md#nanostorage)**.
diff --git a/Nano.Storage.Azure/AzureFileshareProvider.cs b/Nano.Storage.Azure/AzureFileshareProvider.cs
index 0d762fda..982906e0 100644
--- a/Nano.Storage.Azure/AzureFileshareProvider.cs
+++ b/Nano.Storage.Azure/AzureFileshareProvider.cs
@@ -14,7 +14,7 @@ namespace Nano.Storage.Azure;
/// This Nano provider registers Azure File Sharerelated services based on the supplied .
/// When health checks are enabled, it adds an Azure File Share health check to the application's health check pipeline.
///
-/// Documentation: https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Storage.Azure/README.md/nanostorageazure
+/// Documentation: https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Storage.Azure/README.md/nanostorageazure
public sealed class AzureFileshareProvider : IStorageProvider
{
///
diff --git a/Nano.Storage.Azure/README.md b/Nano.Storage.Azure/README.md
index 5361e8bd..e4a52e7e 100644
--- a/Nano.Storage.Azure/README.md
+++ b/Nano.Storage.Azure/README.md
@@ -8,12 +8,12 @@
***
## Table of Contents
-* **[Home](https://github.com/Nano-Core/Nano.Library/tree/master/README.md#nanolibrary)**
+* **[Home](https://github.com/Nano-Core/Nano.Library/blob/master/README.md#nanolibrary)**
* **[Summary](#summary)**
* **[Registration](#registration)**
* **[Configuration](#configuration)**
* **[Docker Compose](#docker-compose)**
-* **[Kuberentes](#kuberentes)**
+* **[Kubernetes](#kubernetes)**
* **[GitHub Actions](#github-actions)**
## Summary
@@ -24,11 +24,11 @@ enables your application to read from and write to the storage directly, while t
No changes to your application code are required and you can interact with the file share using the `IPathProvider` interface.
-> π Learn more about **[Nano Storage](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Storage/README.md/nanostorage)**.
-> π Learn more about **[Nano Azure File Share](https://github.com/Nano-Core/Nano.Azure/tree/master/Nano.Azure.Storage/README.md#nanoazurestorage)**.
+> π Learn more about **[Nano Storage](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Storage/README.md#nanostorage)**.
+> π Learn more about **[Nano Azure File Share](https://github.com/Nano-Core/Nano.Azure/blob/master/Nano.Azure.Storage/README.md#nanoazurestorage)**.
-Try it out yourself using the **[Api.Storage.Azure](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Storage.Azure)** or
-**[Console.Storage.Azure](https://github.com/Nano-Core/Nano.Lessons/tree/master/Console.Storage.Azure)** example.
+Try it out yourself using the **[Api.Storage.Azure](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Storage.Azure)** or
+**[Console.Storage.Azure](https://github.com/Nano-Core/Nano.Lessons/blob/master/Console.Storage.Azure)** example.
## Registration
Install the **[Nano.Storage.Azure](https://www.nuget.org/packages/Nano.Storage.Azure)** NuGet package.
diff --git a/Nano.Storage.Local/LocalFileShareProvider.cs b/Nano.Storage.Local/LocalFileShareProvider.cs
index 8044c3ea..16316972 100644
--- a/Nano.Storage.Local/LocalFileShareProvider.cs
+++ b/Nano.Storage.Local/LocalFileShareProvider.cs
@@ -23,7 +23,7 @@ namespace Nano.Storage.Local;
/// When health checks are enabled via ,
/// a lightweight file system health check is registered to verify that the configured storage path exists and is accessible.
///
-/// Documentation: https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Storage.Local/README.md/nanostoragelocal
+/// Documentation: https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Storage.Local/README.md/nanostoragelocal
///
public sealed class LocalFileShareProvider : IStorageProvider
{
diff --git a/Nano.Storage.Local/README.md b/Nano.Storage.Local/README.md
index 4e03d9c0..bc9e03cc 100644
--- a/Nano.Storage.Local/README.md
+++ b/Nano.Storage.Local/README.md
@@ -8,12 +8,12 @@
***
## Table of Contents
-* **[Home](https://github.com/Nano-Core/Nano.Library/tree/master/README.md#nanolibrary)**
+* **[Home](https://github.com/Nano-Core/Nano.Library/blob/master/README.md#nanolibrary)**
* **[Summary](#summary)**
* **[Registration](#registration)**
* **[Configuration](#configuration)**
* **[Docker Compose](#docker-compose)**
-* **[Kuberentes](#kuberentes)**
+* **[Kubernetes](#kubernetes)**
* **[GitHub Actions](#github-actions)**
## Summary
@@ -21,10 +21,10 @@ Storage provider implementation for local file shares.
This provider is intended for mapping a Kubernetes persistent volume as a local file system. Registering it with Nano gives you access to the `IPathProvider` interface.
-> π Learn more about **[Nano Storage](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Storage/README.md/nanostorage)**.
+> π Learn more about **[Nano Storage](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Storage/README.md#nanostorage)**.
-Try it out yourself using the **[Api.Storage.Local](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api.Storage.Local)** or
-**[Console.Storage.Local](https://github.com/Nano-Core/Nano.Lessons/tree/master/Console.Storage.Local)** example.
+Try it out yourself using the **[Api.Storage.Local](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api.Storage.Local)** or
+**[Console.Storage.Local](https://github.com/Nano-Core/Nano.Lessons/blob/master/Console.Storage.Local)** example.
## Registration
Install the **[Nano.Storage.Local](https://www.nuget.org/packages/Nano.Storage.Local)** NuGet package.
diff --git a/Nano.Storage/Abstractions/IStorageProvider.cs b/Nano.Storage/Abstractions/IStorageProvider.cs
index 5596f136..d56b8e27 100644
--- a/Nano.Storage/Abstractions/IStorageProvider.cs
+++ b/Nano.Storage/Abstractions/IStorageProvider.cs
@@ -11,7 +11,7 @@ namespace Nano.Storage.Abstractions;
/// Implementations are responsible for registering all required services (such as clients, health checks, and path providers)
/// into the dependency injection container based on the supplied .
///
-/// Documentation: https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Storage/README.md/nanostorage
+/// Documentation: https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Storage/README.md/nanostorage
public interface IStorageProvider
{
///
diff --git a/Nano.Storage/Extensions/ServiceCollectionExtensions.cs b/Nano.Storage/Extensions/ServiceCollectionExtensions.cs
index 382b7acd..2018ccb4 100644
--- a/Nano.Storage/Extensions/ServiceCollectionExtensions.cs
+++ b/Nano.Storage/Extensions/ServiceCollectionExtensions.cs
@@ -24,7 +24,7 @@ public static class ServiceCollectionExtensions
/// - Registers and in the dependency injection container.
///
///
- /// Documentation: https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Storage/README.md/nanostorage
+ /// Documentation: https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Storage/README.md/nanostorage
/// Thrown when is null.
public static IServiceCollection AddNanoStorage(this IServiceCollection services)
where TProvider : IStorageProvider
diff --git a/Nano.Storage/Nano.Storage.csproj b/Nano.Storage/Nano.Storage.csproj
index 590f9b35..1d0fffb2 100644
--- a/Nano.Storage/Nano.Storage.csproj
+++ b/Nano.Storage/Nano.Storage.csproj
@@ -1,7 +1,7 @@
ο»Ώ
-
+
diff --git a/Nano.Storage/README.md b/Nano.Storage/README.md
index a00d76b7..cd4d528d 100644
--- a/Nano.Storage/README.md
+++ b/Nano.Storage/README.md
@@ -10,7 +10,7 @@
***
## Table of Contents
-* **[Home](https://github.com/Nano-Core/Nano.Library/tree/master/README.md#nanolibrary)**
+* **[Home](https://github.com/Nano-Core/Nano.Library/blob/master/README.md#nanolibrary)**
* **[Summary](#summary)**
* **[Registration](#registration)**
* **[Configuration](#configuration)**
@@ -87,7 +87,7 @@ The ```Storage``` section in the configuration defines the storage provider and
}
```
-> π Learn more about **[Application Configuration](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App/README.md#configuration)** here.
+> π Learn more about **[Application Configuration](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App/README.md#configuration)** here.
## Health Checks
When health checks are enabled in the storage configuration, Nano automatically registers a health check for the configured storage provider.
@@ -110,7 +110,7 @@ health check system and can be used by monitoring tools, load balancers, or cont
```
> β οΈ In order for storage healthcheck to take effect, healthchecks must be enabled for the application.
-Read more about **[Nano Health Check](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App.Api/README.md#health-checks)**.
+Read more about **[Nano Health Check](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App.Api/README.md#health-checks)**.
## Storage Providers
Nano provides several storage providers, so usually there is no need to implement a custom provider for your application.
@@ -123,5 +123,5 @@ and then register your provider with the application using `.AddNanoStorage π Explore the full **[Nano Documentation](https://github.com/Nano-Core/Nano.Library/tree/master/README.md#nanolibrary)**.
+> π Explore the full **[Nano Documentation](https://github.com/Nano-Core/Nano.Library/blob/master/README.md#nanolibrary)**.
> β οΈ While this package provides everything out of the box, itβs generally recommended to reference individual Nano packages as needed in your application.
-> Learn more about **[Nano NuGet Packages](https://github.com/Nano-Core/Nano.Library#nuget-packages)**.
+> Learn more about **[Nano NuGet Packages](https://github.com/Nano-Core/Nano.Library#-nuget-packages)**.
diff --git a/QUICK_START.md b/QUICK_START.md
index 79b987e4..9be67199 100644
--- a/QUICK_START.md
+++ b/QUICK_START.md
@@ -5,7 +5,7 @@
***
## Table of Contents
-* **[Home](https://github.com/Nano-Core/Nano.Library/tree/master/README.md#nanolibrary)**
+* **[Home](https://github.com/Nano-Core/Nano.Library/blob/master/README.md#nanolibrary)**
* **[1. Choosing Application Type](#choosing-application-type)**
* **[2. Application Configuration](#application-configuration)**
* **[3. Adding Logging Provider](#adding-logging-provider)**
@@ -16,23 +16,23 @@
* **[8. Congratz, Launch](#congratz-launch)**
## Choosing Application Type
-The first step is to choose the application type that best fits your use case. Nano currently supports three application types: **[Api](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App.Api/README.md#nanoapi)**,
-**[Web](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App.Web/README.md#nanoweb)**, and **[Console](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App.Console/README.md#nanoconsole)**. Each application
+The first step is to choose the application type that best fits your use case. Nano currently supports three application types: **[Api](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App.Api/README.md#nanoapi)**,
+**[Web](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App.Web/README.md#nanoweb)**, and **[Console](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App.Console/README.md#nanoconsole)**. Each application
type is provided as a _blank_ solution template. These templates include the essential project structure, configuration, and dependencies required to get started, without
adding unnecessary complexity.
To begin, copy or clone the solution that matches your chosen application type.
-- **[Api._Blank](https://github.com/Nano-Core/Nano.Lessons/tree/master/Api._Blank)**
-- **[Console._Blank](https://github.com/Nano-Core/Nano.Lessons/tree/master/Console._Blank)**
-- **[Web._Blank](https://github.com/Nano-Core/Nano.Lessons/tree/master/Web._Blank)**
+- **[Api._Blank](https://github.com/Nano-Core/Nano.Lessons/blob/master/Api._Blank)**
+- **[Console._Blank](https://github.com/Nano-Core/Nano.Lessons/blob/master/Console._Blank)**
+- **[Web._Blank](https://github.com/Nano-Core/Nano.Lessons/blob/master/Web._Blank)**
These templates provide a minimal starting point for each application type.
Then rename the solution and projects to fit your application, updating namespaces and identifiers as needed throughout the files.
At this point, you have a fully functional Nano baseline solution, capable of running locally and deploying to Kubernetes via GitHub Actions. For a detailed overview of the
-included projects, files, and overall structure, see **[Solution Composition](https://github.com/Nano-Core/Nano.Library/tree/master/README.md#solution-composition)**.
+included projects, files, and overall structure, see **[Solution Composition](https://github.com/Nano-Core/Nano.Library/blob/master/README.md#solution-composition)**.
The `program.cs` looks like this.
@@ -94,7 +94,7 @@ sections are set to `null`. Features are enabled on an opt-in basis by configuri
}
````
-> π Learn more about **[Nano Api Configuration](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App.Api/README.md/README.md#configuration)**.
+> π Learn more about **[Nano Api Configuration](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App.Api/README.md/README.md#configuration)**.
For Console applications, the configuration is minimal and straightforward.
@@ -107,12 +107,12 @@ For Console applications, the configuration is minimal and straightforward.
```
-> π Learn more about **[Nano Console Configuration](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App.Console/README.md#configuration)**.
+> π Learn more about **[Nano Console Configuration](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App.Console/README.md#configuration)**.
## Adding Logging Provider
Now that the application has been created and configured, the next step is to add providers that extend the commonly used capabilities of your Nano application.
-First, most applications, if not all, require a **[Logging Provider](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Logging/README.md#nanologging)**. Register it in
+First, most applications, if not all, require a **[Logging Provider](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Logging/README.md#nanologging)**. Register it in
the `ConfigureServices(...)` method in `Program.cs`.
```csharp
@@ -130,10 +130,10 @@ format. The choice of provider is primarily a matter of preference and existing
| Provider | Type | Description |
| ------------------------------------------------------------------------------------------------------------------------------ | --------------------- | --------------------------------------------------------------------------------------- |
-| **[Log4Net](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Logging.Log4Net/README.md#nanologginglog4net)** | `Log4NetProvider` | Console logging using a log4net-based implementation. |
-| **[Microsoft](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Logging.Microsoft/README.md#nanologgingmicrosoft)** | `MicrosoftProvider` | Console logging using the built-in Microsoft.Extensions.Logging abstractions. |
-| **[NLog](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Logging.NLog/README.md#nanologgingnlog)** | `NLog` | Console logging using an NLog-based implementation. |
-| **[Serilog](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Logging.Serilog/README.md#nanologgingserilog)** | `SerilogProvider` | Console logging using a Serilog-based implementation with structured logging support. |
+| **[Log4Net](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Logging.Log4Net/README.md#nanologginglog4net)** | `Log4NetProvider` | Console logging using a log4net-based implementation. |
+| **[Microsoft](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Logging.Microsoft/README.md#nanologgingmicrosoft)** | `MicrosoftProvider` | Console logging using the built-in Microsoft.Extensions.Logging abstractions. |
+| **[NLog](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Logging.NLog/README.md#nanologgingnlog)** | `NLog` | Console logging using an NLog-based implementation. |
+| **[Serilog](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Logging.Serilog/README.md#nanologgingserilog)** | `SerilogProvider` | Console logging using a Serilog-based implementation with structured logging support. |
The logging configuration is straightforward, with sensible default values provided, as shown below.
@@ -145,10 +145,10 @@ The logging configuration is straightforward, with sensible default values provi
}
```
-> π Learn more about **[Logging Configuration](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Logging/README.md#configuration)**.
+> π Learn more about **[Logging Configuration](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Logging/README.md#configuration)**.
## Adding Data Provider
-Moving on to the **[Data Provider](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md)**. This provider is more optional than logging, but still required by
+Moving on to the **[Data Provider](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md)**. This provider is more optional than logging, but still required by
most applications.
Register the Nano Data Provider in the `ConfigureServices(...)` method in `Program.cs`.
@@ -168,11 +168,11 @@ while exposing a consistent abstraction layer.
| Provider | Type | Description |
| -------------------------------------------------------------------------------------------------------------------------- | --------------------- | ------------------------------------------------------------------------ |
-| **[InMemory](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data.InMemory/README.md#nanodatainmemory)** | `InMemoryProvider` | In-memory data provider intended for testing and lightweight scenarios. |
-| **[MySql](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data.MySql/README.md#nanodatamysql)** | `MySqlProvider` | MySQL data provider using Pomelo.EntityFrameworkCore.MySql. |
-| **[PostgreSQL](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data.PostgreSQL/README.md#nanodatapostgresql)** | `PostgreSqlProvider` | PostgreSQL data provider using Npgsql. |
-| **[SqLite](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data.SqLite/README.md#nanodatasqlite)** | `SqLiteProvider` | SQLite data provider. |
-| **[SqlServer](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data.SqlServer/README.md#nanodatasqlserver)** | `SqlServerProvider` | SQL Server data provider. |
+| **[InMemory](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data.InMemory/README.md#nanodatainmemory)** | `InMemoryProvider` | In-memory data provider intended for testing and lightweight scenarios. |
+| **[MySql](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data.MySql/README.md#nanodatamysql)** | `MySqlProvider` | MySQL data provider using Pomelo.EntityFrameworkCore.MySql. |
+| **[PostgreSQL](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data.PostgreSQL/README.md#nanodatapostgresql)** | `PostgreSqlProvider` | PostgreSQL data provider using Npgsql. |
+| **[SqLite](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data.SqLite/README.md#nanodatasqlite)** | `SqLiteProvider` | SQLite data provider. |
+| **[SqlServer](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data.SqlServer/README.md#nanodatasqlserver)** | `SqlServerProvider` | SQL Server data provider. |
The `TContext` defines the Nano `BaseDbContext` implementation. You must create an Entity Framework `DbContext` that derives from `BaseDbContext`.
@@ -213,9 +213,9 @@ The data configuration is straightforward and allows features to be easily enabl
```
Most importantly, the required `ConnectionString` must be configured.
-Also, configuring **[Data Health Check](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md#health-check)** is recommended to ensure system observability.
+Also, configuring **[Data Health Check](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md#health-check)** is recommended to ensure system observability.
-> π Learn more about **[Data Configuration](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md#configuration)**.
+> π Learn more about **[Data Configuration](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md#configuration)**.
Once the data provider has been registered and the configuration is in place, you can start defining Nano entity models and data mappings. Create an entity model by deriving
from `BaseEntity` and adding properties. Then implement the mapping by creating a class that derives from `BaseEntityMapping`, where `TEntity` is your model type. In
@@ -247,30 +247,30 @@ public class MyEntityMapping : BaseEntityMapping
> β οΈ Always ensure you call `base.Configure(builder)`, otherwise inherited Nano properties may not function correctly.
More advanced uses of Nano entity models are also available, including support for user entities used with
-**[Data Identity](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md#didentity)** features, as well as mapping database views as read-only entities.
+**[Data Identity](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md#didentity)** features, as well as mapping database views as read-only entities.
-> π Learn more about **[Nano Data Models](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md#data-models)** and
-**[Nano Data Mappings](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data#configuration/README.md#data-mappings)**.
+> π Learn more about **[Nano Data Models](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md#data-models)** and
+**[Nano Data Mappings](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data#configuration/README.md#data-mappings)**.
-For entity models where you want **[Soft Delete](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md#soft-delete)** instead of the default hard delete behavior,
+For entity models where you want **[Soft Delete](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md#soft-delete)** instead of the default hard delete behavior,
implement the `IEntitySoftDelete` interface on your entity model.
-Nano also supports **[Entity Events](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md#entity-events)**, enabling asynchronous synchronization of entity models
+Nano also supports **[Entity Events](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md#entity-events)**, enabling asynchronous synchronization of entity models
between applications. To publish changes for an entity, add the `[Publish]` attribute to the entity model class definition. In the consuming application, create a corresponding
entity model with the same name and annotate it with the `[Subscribe]` attribute. It will then receive events whenever the entity is created, updated, or deleted. Additional
properties can be included in published events, making it easy to synchronize commonly shared data across different parts of the system.
Entity events require an Eventing Provider to be registered (see further sections).
-Another noteworthy feature of the data provider is the **[`[Include] Attribute`](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md#include-annotation)**. Navigation
+Another noteworthy feature of the data provider is the **[`[Include] Attribute`](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md#include-annotation)**. Navigation
properties on entity models can be annotated with this attribute to create a graph-lite structure. When an entity is retrieved through the
-**[Data Repositories](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md#repositories)**, all included navigation properties are automatically loaded as part
+**[Data Repositories](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md#repositories)**, all included navigation properties are automatically loaded as part
of the query.
-> π Learn more about the other **[Nano Data](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md)** features.
+> π Learn more about the other **[Nano Data](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md)** features.
## Adding Eventing Provider
-Adding an **[Eventing Provider](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Eventing/README.md)** (message queueing) follows the same pattern as the other Nano providers.
+Adding an **[Eventing Provider](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Eventing/README.md)** (message queueing) follows the same pattern as the other Nano providers.
```csharp
...
@@ -286,7 +286,7 @@ The `TProvider` defines the eventing implementation used by your application. Th
| Provider | Type | Description |
| ------------------------------------------------------------------------------------------------------------------------------ | ------------------- | ------------------------------------------------------------------------------------------------------- |
-| **[RabbitMq](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Eventing.RabbitMq/README.md#nanoeventingrabbitmq)** | `RabbitMqProvider` | Message broker-based eventing using RabbitMQ for reliable asynchronous communication between services. |
+| **[RabbitMq](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Eventing.RabbitMq/README.md#nanoeventingrabbitmq)** | `RabbitMqProvider` | Message broker-based eventing using RabbitMQ for reliable asynchronous communication between services. |
And again, the configuration is straightforward.
@@ -308,9 +308,9 @@ And again, the configuration is straightforward.
```
Most importantly, the required `Host` and `Credentials` must be configured.
-Also, configuring **[Data Health Check](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Eventing/README.md#health-check)** is recommended to ensure system observability.
+Also, configuring **[Data Health Check](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Eventing/README.md#health-check)** is recommended to ensure system observability.
-> π Learn more about **[Eventing Configuration](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Eventing/README.md#configuration)**.
+> π Learn more about **[Eventing Configuration](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Eventing/README.md#configuration)**.
When an eventing provider has been registered, it exposes the `IEventing` interface, which can be injected to publish custom event contracts from anywhere in the application.
@@ -346,10 +346,10 @@ public class MyEventingHandler() : BaseEventHandler(routingKey: null, o
}
```
-> π Learn more about the other **[Nano Eventing](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Eventing/README.md#nanoeventing)** features.
+> π Learn more about the other **[Nano Eventing](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Eventing/README.md#nanoeventing)** features.
## Adding Storage Provider
-The **[Storage Provider](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Storage/README.md/README.md#nanostorage)** can be added by registering
+The **[Storage Provider](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Storage/README.md/README.md#nanostorage)** can be added by registering
it in the `ConfigureServices(...)` method in `Program.cs`.
```csharp
@@ -366,8 +366,8 @@ The `TProvider` defines the storage implementation used by your application. The
| Provider | Type | Description |
| ------------------------------------------------------------------------------------------------------------------- | ------------------------- | ------------------------------------------------------------ |
-| **[Azure](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Storage.Azure/README.md#nanostorageazure)** | `AzureFileshareProvider` | Nano Storage provider implementation for Azure File Shares. |
-| **[Local](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Storage.Local/README.md#nanostoragelocal)** | `LocalFileShareProvider` | Storage provider for local file systemβbacked storage. |
+| **[Azure](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Storage.Azure/README.md#nanostorageazure)** | `AzureFileshareProvider` | Nano Storage provider implementation for Azure File Shares. |
+| **[Local](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Storage.Local/README.md#nanostoragelocal)** | `LocalFileShareProvider` | Storage provider for local file systemβbacked storage. |
And configuration.
@@ -383,19 +383,19 @@ And configuration.
```
Most importantly, the required `ShareName` and `Credentials` must be configured.
-Also, configuring **[Storage Health Check](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Storage/README.md#health-check)** is recommended to ensure system observability.
+Also, configuring **[Storage Health Check](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Storage/README.md#health-check)** is recommended to ensure system observability.
-> π Learn more about **[Storage Configuration](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Storage/README.md#configuration)**.
+> π Learn more about **[Storage Configuration](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Storage/README.md#configuration)**.
Once a storage provider has been registered, it exposes the `IPathProvider` interface. This can be injected anywhere in the application to provide easy access to the configured
root path of the file storage location.
-> π Learn more about the other **[Nano Storage](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Storage/README.md)** features.
+> π Learn more about the other **[Nano Storage](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Storage/README.md)** features.
## 8. Implementing Your Application Domain
Now it is time to implement the actual domain of your application. At this stage, you start defining the application-specific behavior and structure. Depending on the application
-type, different building blocks are available. For web-based applications, you typically define **[Controllers](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App.Api/README.md#controllers)**,
-while for console-based applications, you implement **[Console Workers](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App.Console/README.md#console-workers)**.
+type, different building blocks are available. For web-based applications, you typically define **[Controllers](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App.Api/README.md#controllers)**,
+while for console-based applications, you implement **[Console Workers](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App.Console/README.md#console-workers)**.
#### API-based applications
First, here is an example of an entity controller that works with your data model and exposes standard Create, Read, Update, and Delete (CRUD) endpoints.
@@ -436,7 +436,7 @@ public class MyEntityQueryCriteria : BaseQueryCriteria
}
```
-Controllers can later be consumed by other applications through the **[Nano Api Client](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App/README.md#api-clients)**. To do this,
+Controllers can later be consumed by other applications through the **[Nano Api Client](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App/README.md#api-clients)**. To do this,
create an implementation that derives from `BaseApiClient` and include itβalong with the relevant entity modelsβin the consuming application. This provides a simple and consistent
way to connect to the service and use its entity functionality.
diff --git a/README.md b/README.md
index 3372ac8c..187dfadc 100644
--- a/README.md
+++ b/README.md
@@ -29,14 +29,14 @@
βοΈ **[Licenses](#-licenses)**
### Documentation
- π **[Applications](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App#README.md#nanoapp)**
- π‘ **[Api](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App.Api/README.md#nanoappapi)**
- βοΈ **[Console](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App.Console/README.md#nanoappconsole)**
- π **[Web](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App.Web/README.md#nanoappweb)**
- π **[Logging](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Logging/README.md#nanologging)**
- π’οΈ **[Data](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md#nanodata)**
- β‘ **[Eventing](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Eventing/README.md#nanoeventing)**
- π **[Storage](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Storage/README.md#nanostorage)**
+ π **[Applications](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App/README.md#nanoapp)**
+ π‘ **[Api](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App.Api/README.md#nanoappapi)**
+ βοΈ **[Console](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App.Console/README.md#nanoappconsole)**
+ π **[Web](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App.Web/README.md#nanoappweb)**
+ π **[Logging](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Logging/README.md#nanologging)**
+ π’οΈ **[Data](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md#nanodata)**
+ β‘ **[Eventing](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Eventing/README.md#nanoeventing)**
+ π **[Storage](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Storage/README.md#nanostorage)**
## π Summary
Nano is a lightweight library for rapidly building modern .NET applications.
@@ -59,23 +59,23 @@ more, Nano helps cover the full application lifecycle, from development and conf
To support production-grade environments, Nano also provides the foundation for running applications securely and at scale in Kubernetes on Azure. Nano includes ready-to-use templates
for Kubernetes and GitHub Actions, enabling consistent CI/CD pipelines and infrastructure provisioning.
-> π Learn more about **[Nano.Azure](https://github.com/Nano-Core/Nano.Azure/README.md#nanoazure)** and **[Nano.Azure.Kubernetes](https://github.com/Nano-Core/Nano.Azure.Kubernetes/README.md#nanoazurekubernetes)**
+> π Learn more about **[Nano.Azure](https://github.com/Nano-Core/Nano.Azure/blob/master/README.md#nanoazure)** and **[Nano.Azure.Kubernetes](https://github.com/Nano-Core/Nano.Azure.Kubernetes/blob/master/README.md#nanoazurekubernetes)**
Together, these capabilities make Nano a strong choice for designing, building, and maintaining microservice architectures, even for small teams.
### π Launch Your App in Under 60 Minutes
-Get started quickly by building your own Nano **[Api](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App.Api/README.md&nanoapi)**, **[Web](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App.Web/README.md#nanoweb)**,
-or **[Console](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App.Console/README.md#nanoconsole)** application, and have it configured and running in less than an hour. Nano follows a flexible,
-opt-in approach, allowing you to configure and enable only the features you need. For the four core pillars of distributed systems, **[Logging](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Logging/README.md#nanologging)**,
-**[Data](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md#nanodata)**, **[Eventing](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Eventing/README.md#nanoeventing)**,
-and **[Storage](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Storage#/README.md#nanostorage)**, Nano provides pluggable providers that integrate seamlessly into your application.
+Get started quickly by building your own Nano **[Api](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App.Api/README.md#nanoappapi)**, **[Web](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App.Web/README.md#nanoappweb)**,
+or **[Console](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App.Console/README.md#nanoappconsole)** application, and have it configured and running in less than an hour. Nano follows a flexible,
+opt-in approach, allowing you to configure and enable only the features you need. For the four core pillars of distributed systems, **[Logging](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Logging/README.md#nanologging)**,
+**[Data](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md#nanodata)**, **[Eventing](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Eventing/README.md#nanoeventing)**,
+and **[Storage](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Storage/README.md#nanostorage)**, Nano provides pluggable providers that integrate seamlessly into your application.
Simply choose and configure the providers that match your requirements for each pillar, and Nano handles the rest.
-Itβs recommended to start with the **[Quick Start Guide](https://github.com/Nano-Core/Nano.Library/tree/master/QUICK_START.md)** to get familiar with Nano, and then continue exploring
+Itβs recommended to start with the **[Quick Start Guide](https://github.com/Nano-Core/Nano.Library/blob/master/QUICK_START.md#quick-start-guide)** to get familiar with Nano, and then continue exploring
the documentation for applications and providers to learn how to configure, use, and customize it. You can also dive into **[Nano.Lessons](https://github.com/Nano-Core/Nano.Lessons)**,
which contains **100+** focused examples that demonstrate individual features in isolation.
-> π‘ Explore API requests for all lessons in our **[Public Nano Workspace on Postman](https://www.postman.com/nanocore/nano-lessons)**.
+> π‘ Explore API requests for all lessons in our **[Public Nano Workspace on Postman](https://www.postman.com/nanocore)**.
## β¨ Highlighted features
@@ -90,7 +90,7 @@ In addition to built-in capabilities, Nano supports extending API clients with c
functionality. Authentication, headers, and request metadata are handled automatically, including secure propagation between services. This ensures reliable, consistent, and
secure communication across all connected Nano applications without additional boilerplate.
-> π Learn more about **[Api Clients](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App/README#api-clients)**
+> π Learn more about **[Api Clients](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App/README.md#api-clients)**
### β¨ Entity Eventing
Entity Events in Nano provide a lightweight, attribute-driven mechanism for synchronizing entity changes across distributed applications. They automatically propagate create, update,
@@ -104,7 +104,7 @@ dependent entities to propagate back to root aggregates.
This model reduces coupling between services while maintaining data consistency across boundaries.
-> π Learn more about **[Entity Eventing](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md#entity-eventing)**
+> π Learn more about **[Entity Eventing](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md#entity-events)**
### β¨ Include Annotation (graph-lite)
Nanoβs Include feature automatically loads navigation properties when retrieving entities through repositories, enabling full entity graphs with recursive inclusion up to a configured
@@ -113,7 +113,7 @@ depth. It supports both references and collections, simplifying data access for
This is especially useful when you want to work with complete object graphs instead of manually composing related data. However, inclusion can be selectively controlled per query,
allowing you to retrieve only the main entity when full graphs are not needed.
-> π Learn more about **[Include Annotations](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.Data/README.md#include-annotation)**
+> π Learn more about **[Include Annotations](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.Data/README.md#include-annotation)**
### β¨ Cascading Health Checks
Nano provides built-in health checks exposed through a /healthz endpoint for monitoring application status.
@@ -123,7 +123,7 @@ failures propagate through related components and applications to provide a cons
In addition, custom health checks can be registered during application startup, allowing application-specific components to integrate seamlessly into the same monitoring system.
-> π Learn more about **[Api Health Checks](https://github.com/Nano-Core/Nano.Library/tree/master/Nano.App.Api/README.md#health-checks)**
+> π Learn more about **[Api Health Checks](https://github.com/Nano-Core/Nano.Library/blob/master/Nano.App.Api/README.md#health-checks)**
## ποΈ Nano Architectures
Nano supports multiple distributed architecture styles, depending on the complexity and communication patterns of your system.
@@ -131,9 +131,11 @@ Nano supports multiple distributed architecture styles, depending on the complex
| Architecture | Description |
| ------------------------------------------------ | -------------------------------------------------------------------------------- |
| Solo Application | A single, independent application. |
-| Microservice Orchestration (Top-down) | API-driven orchestration where a central API coordinates downstream services. |
+| Microservice Orchestration (Top-Down) | API-driven orchestration where a central API coordinates downstream services. |
| Microservice Orchestration (Service-to-Service) | Decentralized communication where services interact directly with each other. |
+
+
## βοΈ Required Tools
Before getting started, make sure you have the following tools installed and configured.