Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
7562211
build(templates): scaffold SquidStd.Templates pack with pack-time ver…
tgiachi Jun 23, 2026
8881f32
fix(templates): emit template content in pack (disable symbols, TFM c…
tgiachi Jun 23, 2026
5aacc48
feat(templates): add squidstd-host console template
tgiachi Jun 23, 2026
58ec1a4
feat(templates): add squidstd-aspnetcore minimal API template
tgiachi Jun 23, 2026
9642944
feat(templates): add squidstd-worker microservice template with messa…
tgiachi Jun 23, 2026
54f6958
feat(templates): add squidstd-manager ASP.NET template with messaging…
tgiachi Jun 23, 2026
7e07dac
test(templates): add isolated-hive instantiation tests for the templa…
tgiachi Jun 23, 2026
b5d93cd
docs(templates): add README, DocFX article and index entries for Squi…
tgiachi Jun 23, 2026
e68a595
merge: SquidStd.Templates dotnet new pack (host, aspnetcore, worker, …
tgiachi Jun 23, 2026
874605d
build(search): scaffold SquidStd.Search.Abstractions and SquidStd.Sea…
tgiachi Jun 23, 2026
df6daa2
feat(search): add IIndexableEntity, SearchIndexAttribute, ISearchServ…
tgiachi Jun 23, 2026
d9f70e0
feat(search): add SearchIndexNameResolver with env-variable expansion
tgiachi Jun 23, 2026
98d5a5a
feat(search): add Elasticsearch options, transport helper, registrati…
tgiachi Jun 23, 2026
f9f16a3
feat(search): add LINQ-to-Elasticsearch expression translator
tgiachi Jun 23, 2026
a13e14f
feat(search): add Elasticsearch IQueryable provider with async terminals
tgiachi Jun 23, 2026
2b29966
test(search): add Elasticsearch integration tests; send JSON/NDJSON c…
tgiachi Jun 23, 2026
f230986
docs(search): add READMEs, DocFX articles and index entries for the s…
tgiachi Jun 23, 2026
7d05140
merge: SquidStd.Search.Abstractions + SquidStd.Search.Elasticsearch (…
tgiachi Jun 23, 2026
95dcd73
build(mail): scaffold SquidStd.Mail.Abstractions and SquidStd.Mail.Ma…
tgiachi Jun 24, 2026
ebb7ffa
feat(mail): add MailMessage, MailReceivedEvent, IMailReader and MailO…
tgiachi Jun 24, 2026
92d18c0
feat(mail): add MimeMessageMapper from MimeMessage to MailMessage
tgiachi Jun 24, 2026
2e48a79
feat(mail): add ImapMailReader fetching unseen messages
tgiachi Jun 24, 2026
bf9e315
feat(mail): add Pop3MailReader with UIDL dedup and optional delete
tgiachi Jun 24, 2026
935c7be
feat(mail): add MailPollingService publishing MailReceivedEvent on th…
tgiachi Jun 24, 2026
839c85a
feat(mail): add AddMail registration with protocol-specific reader an…
tgiachi Jun 24, 2026
cfcba5f
test(mail): add GreenMail integration tests for IMAP, POP3 and polling
tgiachi Jun 24, 2026
882f529
docs(mail): add READMEs, DocFX articles and index entries for the mai…
tgiachi Jun 24, 2026
0ad48f9
merge: SquidStd.Mail.Abstractions + SquidStd.Mail.MailKit (IMAP/POP3 …
tgiachi Jun 24, 2026
65cd6f4
feat(mail): add outbound contracts (IMailSender, OutgoingMailMessage,…
tgiachi Jun 24, 2026
5943e83
feat(mail): add OutgoingMessageMapper to MimeMessage
tgiachi Jun 24, 2026
0d3d7e2
feat(mail): add MailKitMailSender sending via SMTP with send events
tgiachi Jun 24, 2026
ec121ad
fix(mail): pass explicit CancellationToken.None on failure-event publish
tgiachi Jun 24, 2026
f2458c4
feat(mail): add AddMailSender registration for the SMTP sender
tgiachi Jun 24, 2026
2495743
test(mail): add GreenMail integration tests for the SMTP sender
tgiachi Jun 24, 2026
1dbf4cc
docs(mail): document the SMTP sender (AddMailSender / SendAsync)
tgiachi Jun 24, 2026
4eafb75
merge: SquidStd.Mail SMTP sender (IMailSender, OutgoingMailMessage, s…
tgiachi Jun 24, 2026
dee830b
build(mail): scaffold SquidStd.Mail.Queue project
tgiachi Jun 24, 2026
1e626e0
feat(mail): add IMailQueue and MailQueue publishing to the messaging …
tgiachi Jun 24, 2026
226d0f1
feat(mail): add MailSendConsumerService and AddMailQueue registration
tgiachi Jun 24, 2026
86500a7
test(mail): cover consumer delivery and retry-to-dead-letter
tgiachi Jun 24, 2026
cc896da
test(mail): add GreenMail end-to-end test for the mail send queue
tgiachi Jun 24, 2026
1faa500
docs(mail): add README, DocFX article and index entry for SquidStd.Ma…
tgiachi Jun 24, 2026
a4235af
merge: SquidStd.Mail.Queue outbound send queue (enqueue + consumer + …
tgiachi Jun 24, 2026
2d33a68
style: apply repository-wide code formatting
tgiachi Jun 24, 2026
d0cd237
docs(tutorials): scaffold Tutorials section, toc and samples folder
tgiachi Jun 24, 2026
0bdf1cc
docs(tutorials): add getting-started tutorial and sample
tgiachi Jun 24, 2026
041c484
docs(tutorials): add events-jobs-scheduling tutorial and sample
tgiachi Jun 24, 2026
5e65090
docs(tutorials): add caching tutorial and sample
tgiachi Jun 24, 2026
b050da4
docs(tutorials): add messaging tutorial and sample
tgiachi Jun 24, 2026
e6c0004
docs(tutorials): add storage, database, messaging-consumers, aspnetco…
tgiachi Jun 24, 2026
ce7bc0b
docs(tutorials): link to source articles (.md) so DocFX resolves cros…
tgiachi Jun 24, 2026
904e676
merge: DocFX tutorials + runnable samples for all SquidStd libraries
tgiachi Jun 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 2 additions & 2 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,15 @@

<!-- Package Icon -->
<ItemGroup Condition="Exists('$(MSBuildThisFileDirectory)assets/icon.png')">
<None Include="$(MSBuildThisFileDirectory)assets/icon.png" Pack="true" PackagePath="" Visible="false" />
<None Include="$(MSBuildThisFileDirectory)assets/icon.png" Pack="true" PackagePath="" Visible="false"/>
</ItemGroup>

<!-- Package Readme (opt-in per project that ships a README.md) -->
<PropertyGroup Condition="Exists('$(MSBuildProjectDirectory)/README.md')">
<PackageReadmeFile>README.md</PackageReadmeFile>
</PropertyGroup>
<ItemGroup Condition="Exists('$(MSBuildProjectDirectory)/README.md')">
<None Include="README.md" Pack="true" PackagePath="\" Visible="false" />
<None Include="README.md" Pack="true" PackagePath="\" Visible="false"/>
</ItemGroup>

</Project>
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,15 @@ block until cancellation for long-running hosts.
| `SquidStd.Storage.S3` | S3/MinIO storage backend (`AddS3Storage`). | [![readme](https://img.shields.io/badge/readme-1390A3.svg)](src/SquidStd.Storage.S3/README.md) · [![NuGet](https://img.shields.io/nuget/v/SquidStd.Storage.S3.svg)](https://www.nuget.org/packages/SquidStd.Storage.S3/) |
| `SquidStd.Scripting.Lua` | Lua scripting engine with attribute-based modules and event bridging. | [![readme](https://img.shields.io/badge/readme-1390A3.svg)](src/SquidStd.Scripting.Lua/README.md) · [![NuGet](https://img.shields.io/nuget/v/SquidStd.Scripting.Lua.svg)](https://www.nuget.org/packages/SquidStd.Scripting.Lua/) |
| `SquidStd.Templating` | Scriban templating with a named-template registry and `templates/*.tmpl` auto-load (`AddTemplating`). | [![readme](https://img.shields.io/badge/readme-1390A3.svg)](src/SquidStd.Templating/README.md) · [![NuGet](https://img.shields.io/nuget/v/SquidStd.Templating.svg)](https://www.nuget.org/packages/SquidStd.Templating/) |
| `SquidStd.Workers.Abstractions` | Worker/manager shared contracts (`JobRequest`, `WorkerHeartbeat`, `WorkerInfo`, `WorkerChannels`). | [![readme](https://img.shields.io/badge/readme-1390A3.svg)](src/SquidStd.Workers.Abstractions/README.md) · [![NuGet](https://img.shields.io/nuget/v/SquidStd.Workers.Abstractions.svg)](https://www.nuget.org/packages/SquidStd.Workers.Abstractions/) |
| `SquidStd.Workers` | Worker runtime: consume jobs, dispatch to `IJobHandler`s, publish heartbeats (`AddWorkers`). | [![readme](https://img.shields.io/badge/readme-1390A3.svg)](src/SquidStd.Workers/README.md) · [![NuGet](https://img.shields.io/nuget/v/SquidStd.Workers.svg)](https://www.nuget.org/packages/SquidStd.Workers/) |
| `SquidStd.Workers.Manager` | Job enqueue, heartbeat registry, offline sweep, opt-in ASP.NET endpoints (`AddWorkerManager`). | [![readme](https://img.shields.io/badge/readme-1390A3.svg)](src/SquidStd.Workers.Manager/README.md) · [![NuGet](https://img.shields.io/nuget/v/SquidStd.Workers.Manager.svg)](https://www.nuget.org/packages/SquidStd.Workers.Manager/) |
| `SquidStd.Templates` | `dotnet new` templates for scaffolding SquidStd projects (host, ASP.NET, worker, manager). | [![readme](https://img.shields.io/badge/readme-1390A3.svg)](src/SquidStd.Templates/README.md) · [![NuGet](https://img.shields.io/nuget/v/SquidStd.Templates.svg)](https://www.nuget.org/packages/SquidStd.Templates/) |
| `SquidStd.Search.Abstractions` | Search/indexing contracts (`IIndexableEntity`, `[SearchIndex]`, `ISearchService`). | [![readme](https://img.shields.io/badge/readme-1390A3.svg)](src/SquidStd.Search.Abstractions/README.md) · [![NuGet](https://img.shields.io/nuget/v/SquidStd.Search.Abstractions.svg)](https://www.nuget.org/packages/SquidStd.Search.Abstractions/) |
| `SquidStd.Search.Elasticsearch` | Elasticsearch indexing + constrained LINQ query provider (`AddElasticsearch`). | [![readme](https://img.shields.io/badge/readme-1390A3.svg)](src/SquidStd.Search.Elasticsearch/README.md) · [![NuGet](https://img.shields.io/nuget/v/SquidStd.Search.Elasticsearch.svg)](https://www.nuget.org/packages/SquidStd.Search.Elasticsearch/) |
| `SquidStd.Mail.Abstractions` | Mail contracts (`MailMessage`, `MailReceivedEvent`, `IMailReader`, `MailOptions`). | [![readme](https://img.shields.io/badge/readme-1390A3.svg)](src/SquidStd.Mail.Abstractions/README.md) · [![NuGet](https://img.shields.io/nuget/v/SquidStd.Mail.Abstractions.svg)](https://www.nuget.org/packages/SquidStd.Mail.Abstractions/) |
| `SquidStd.Mail.MailKit` | IMAP/POP3 mail poller that publishes `MailReceivedEvent` (`AddMail`). | [![readme](https://img.shields.io/badge/readme-1390A3.svg)](src/SquidStd.Mail.MailKit/README.md) · [![NuGet](https://img.shields.io/nuget/v/SquidStd.Mail.MailKit.svg)](https://www.nuget.org/packages/SquidStd.Mail.MailKit/) |
| `SquidStd.Mail.Queue` | Outbound mail send queue over the messaging queue (`AddMailQueue`, `IMailQueue`). | [![readme](https://img.shields.io/badge/readme-1390A3.svg)](src/SquidStd.Mail.Queue/README.md) · [![NuGet](https://img.shields.io/nuget/v/SquidStd.Mail.Queue.svg)](https://www.nuget.org/packages/SquidStd.Mail.Queue/) |

## Architecture

Expand Down
68 changes: 45 additions & 23 deletions SquidStd.slnx
Original file line number Diff line number Diff line change
@@ -1,29 +1,51 @@
<Solution>
<Folder Name="/src/">
<Project Path="src/SquidStd.Abstractions/SquidStd.Abstractions.csproj" />
<Project Path="src/SquidStd.AspNetCore/SquidStd.AspNetCore.csproj" />
<Project Path="src/SquidStd.Caching.Abstractions/SquidStd.Caching.Abstractions.csproj" />
<Project Path="src/SquidStd.Caching.Redis/SquidStd.Caching.Redis.csproj" />
<Project Path="src/SquidStd.Caching/SquidStd.Caching.csproj" />
<Project Path="src/SquidStd.Core/SquidStd.Core.csproj" />
<Project Path="src/SquidStd.Database.Abstractions/SquidStd.Database.Abstractions.csproj" />
<Project Path="src/SquidStd.Database/SquidStd.Database.csproj" />
<Project Path="src/SquidStd.Messaging.Abstractions/SquidStd.Messaging.Abstractions.csproj" />
<Project Path="src/SquidStd.Messaging.RabbitMq/SquidStd.Messaging.RabbitMq.csproj" />
<Project Path="src/SquidStd.Messaging/SquidStd.Messaging.csproj" />
<Project Path="src/SquidStd.Network/SquidStd.Network.csproj" />
<Project Path="src/SquidStd.Plugin.Abstractions/SquidStd.Plugin.Abstractions.csproj" />
<Project Path="src/SquidStd.Scripting.Lua/SquidStd.Scripting.Lua.csproj" />
<Project Path="src/SquidStd.Services.Core/SquidStd.Services.Core.csproj" />
<Project Path="src/SquidStd.Storage.Abstractions/SquidStd.Storage.Abstractions.csproj" />
<Project Path="src/SquidStd.Storage.S3/SquidStd.Storage.S3.csproj" />
<Project Path="src/SquidStd.Storage/SquidStd.Storage.csproj" />
<Project Path="src/SquidStd.Templating/SquidStd.Templating.csproj" />
<Project Path="src/SquidStd.Workers.Abstractions/SquidStd.Workers.Abstractions.csproj" />
<Project Path="src/SquidStd.Workers/SquidStd.Workers.csproj" />
<Project Path="src/SquidStd.Workers.Manager/SquidStd.Workers.Manager.csproj" />
<Project Path="src/SquidStd.Abstractions/SquidStd.Abstractions.csproj"/>
<Project Path="src/SquidStd.AspNetCore/SquidStd.AspNetCore.csproj"/>
<Project Path="src/SquidStd.Caching.Abstractions/SquidStd.Caching.Abstractions.csproj"/>
<Project Path="src/SquidStd.Caching.Redis/SquidStd.Caching.Redis.csproj"/>
<Project Path="src/SquidStd.Caching/SquidStd.Caching.csproj"/>
<Project Path="src/SquidStd.Core/SquidStd.Core.csproj"/>
<Project Path="src/SquidStd.Database.Abstractions/SquidStd.Database.Abstractions.csproj"/>
<Project Path="src/SquidStd.Database/SquidStd.Database.csproj"/>
<Project Path="src/SquidStd.Messaging.Abstractions/SquidStd.Messaging.Abstractions.csproj"/>
<Project Path="src/SquidStd.Messaging.RabbitMq/SquidStd.Messaging.RabbitMq.csproj"/>
<Project Path="src/SquidStd.Messaging/SquidStd.Messaging.csproj"/>
<Project Path="src/SquidStd.Network/SquidStd.Network.csproj"/>
<Project Path="src/SquidStd.Plugin.Abstractions/SquidStd.Plugin.Abstractions.csproj"/>
<Project Path="src/SquidStd.Scripting.Lua/SquidStd.Scripting.Lua.csproj"/>
<Project Path="src/SquidStd.Services.Core/SquidStd.Services.Core.csproj"/>
<Project Path="src/SquidStd.Storage.Abstractions/SquidStd.Storage.Abstractions.csproj"/>
<Project Path="src/SquidStd.Storage.S3/SquidStd.Storage.S3.csproj"/>
<Project Path="src/SquidStd.Storage/SquidStd.Storage.csproj"/>
<Project Path="src/SquidStd.Templating/SquidStd.Templating.csproj"/>
<Project Path="src/SquidStd.Workers.Abstractions/SquidStd.Workers.Abstractions.csproj"/>
<Project Path="src/SquidStd.Workers/SquidStd.Workers.csproj"/>
<Project Path="src/SquidStd.Workers.Manager/SquidStd.Workers.Manager.csproj"/>
<Project Path="src/SquidStd.Templates/SquidStd.Templates.csproj"/>
<Project Path="src/SquidStd.Search.Abstractions/SquidStd.Search.Abstractions.csproj"/>
<Project Path="src/SquidStd.Search.Elasticsearch/SquidStd.Search.Elasticsearch.csproj"/>
<Project Path="src/SquidStd.Mail.Abstractions/SquidStd.Mail.Abstractions.csproj"/>
<Project Path="src/SquidStd.Mail.MailKit/SquidStd.Mail.MailKit.csproj"/>
<Project Path="src/SquidStd.Mail.Queue/SquidStd.Mail.Queue.csproj"/>
</Folder>
<Folder Name="/samples/">
<Project Path="samples/SquidStd.Samples.WorkerSystem/SquidStd.Samples.WorkerSystem.csproj" />
<Project Path="samples/SquidStd.Samples.Templating/SquidStd.Samples.Templating.csproj" />
<Project Path="samples/SquidStd.Samples.Storage/SquidStd.Samples.Storage.csproj" />
<Project Path="samples/SquidStd.Samples.Search/SquidStd.Samples.Search.csproj" />
<Project Path="samples/SquidStd.Samples.ScriptingLua/SquidStd.Samples.ScriptingLua.csproj" />
<Project Path="samples/SquidStd.Samples.Plugins/SquidStd.Samples.Plugins.csproj" />
<Project Path="samples/SquidStd.Samples.Networking/SquidStd.Samples.Networking.csproj" />
<Project Path="samples/SquidStd.Samples.Email/SquidStd.Samples.Email.csproj" />
<Project Path="samples/SquidStd.Samples.Database/SquidStd.Samples.Database.csproj" />
<Project Path="samples/SquidStd.Samples.AspNetCore/SquidStd.Samples.AspNetCore.csproj" />
<Project Path="samples/SquidStd.Samples.Messaging/SquidStd.Samples.Messaging.csproj" />
<Project Path="samples/SquidStd.Samples.Caching/SquidStd.Samples.Caching.csproj" />
<Project Path="samples/SquidStd.Samples.EventsJobsScheduling/SquidStd.Samples.EventsJobsScheduling.csproj" />
<Project Path="samples/SquidStd.Samples.GettingStarted/SquidStd.Samples.GettingStarted.csproj" />
</Folder>
<Folder Name="/tests/">
<Project Path="tests/SquidStd.Tests/SquidStd.Tests.csproj" />
<Project Path="tests/SquidStd.Tests/SquidStd.Tests.csproj"/>
</Folder>
</Solution>
1 change: 1 addition & 0 deletions docs/articles/mail-abstractions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[!include[](../../src/SquidStd.Mail.Abstractions/README.md)]
1 change: 1 addition & 0 deletions docs/articles/mail-mailkit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[!include[](../../src/SquidStd.Mail.MailKit/README.md)]
1 change: 1 addition & 0 deletions docs/articles/mail-queue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[!include[](../../src/SquidStd.Mail.Queue/README.md)]
1 change: 1 addition & 0 deletions docs/articles/search-abstractions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[!include[](../../src/SquidStd.Search.Abstractions/README.md)]
1 change: 1 addition & 0 deletions docs/articles/search-elasticsearch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[!include[](../../src/SquidStd.Search.Elasticsearch/README.md)]
1 change: 1 addition & 0 deletions docs/articles/templates.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[!include[](../../src/SquidStd.Templates/README.md)]
12 changes: 12 additions & 0 deletions docs/articles/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@
href: workers.md
- name: SquidStd.Workers.Manager
href: workers-manager.md
- name: SquidStd.Templates
href: templates.md
- name: SquidStd.Search.Abstractions
href: search-abstractions.md
- name: SquidStd.Search.Elasticsearch
href: search-elasticsearch.md
- name: SquidStd.Mail.Abstractions
href: mail-abstractions.md
- name: SquidStd.Mail.MailKit
href: mail-mailkit.md
- name: SquidStd.Mail.Queue
href: mail-queue.md
- name: Serialization
href: serialization.md
- name: Scheduler
Expand Down
2 changes: 1 addition & 1 deletion docs/docfx.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"build": {
"content": [
{ "files": [ "api/**.{yml,md}" ] },
{ "files": [ "articles/**.{md,yml}", "*.md", "toc.yml" ] }
{ "files": [ "articles/**.{md,yml}", "tutorials/**.{md,yml}", "*.md", "toc.yml" ] }
],
"resource": [
{ "files": [ "images/**" ] }
Expand Down
2 changes: 2 additions & 0 deletions docs/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@
href: index.md
- name: Articles
href: articles/
- name: Tutorials
href: tutorials/
- name: API
href: api/
55 changes: 55 additions & 0 deletions docs/tutorials/aspnetcore-app.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Host SquidStd in an ASP.NET Core app

Wire SquidStd into an ASP.NET Core Minimal API and expose its health checks over HTTP.

## What you'll build

A Minimal API web app that uses SquidStd (`SquidStd.AspNetCore`) as its DryIoc-backed service provider, surfaces
the registered SquidStd health checks at `/health`, and answers a simple root endpoint.

## Prerequisites

- .NET 10 SDK
- `dotnet add package SquidStd.AspNetCore`

## Steps

### 1. Register SquidStd on the builder

`UseSquidStd` swaps in DryIoc as the ASP.NET Core service provider and bootstraps SquidStd. The root directory is
taken from the host environment automatically, so you only set the config name.

[!code-csharp[](../../samples/SquidStd.Samples.AspNetCore/Program.cs#step-1)]

### 2. Bridge the health checks

`AddSquidStdHealthChecks` registers every SquidStd `IHealthCheck` as a standard ASP.NET Core health check. Call it
after `UseSquidStd`.

[!code-csharp[](../../samples/SquidStd.Samples.AspNetCore/Program.cs#step-2)]

### 3. Build the app and map endpoints

Build the app, expose the health checks with the standard `MapHealthChecks`, add a root endpoint, and run.

[!code-csharp[](../../samples/SquidStd.Samples.AspNetCore/Program.cs#step-3)]

## Run it

```bash
dotnet run --project samples/SquidStd.Samples.AspNetCore
```

Browse to `/` for the "SquidStd up" message and to `/health` for the aggregated health-check status.

## How it works

`UseSquidStd` creates an owned DryIoc container, registers it through `DryIocServiceProviderFactory`, and hooks the
SquidStd lifecycle into the ASP.NET Core host via a hosted service. `AddSquidStdHealthChecks` resolves the SquidStd
`IHealthCheck` instances from that container and adapts each one into the standard health-check pipeline, so
`MapHealthChecks` reports them like any other ASP.NET Core check.

## See also

- [SquidStd.AspNetCore reference](../articles/aspnetcore.md)
- Previous: [Getting started](getting-started.md)
52 changes: 52 additions & 0 deletions docs/tutorials/caching.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Caching (in-memory + Redis)

Cache typed values with a TTL, then swap the in-memory backend for Redis without changing your code.

## What you'll build

A host that resolves `ICacheService` (`SquidStd.Caching.Abstractions`) backed by the in-memory provider
(`SquidStd.Caching`), and the one-line change to use Redis (`SquidStd.Caching.Redis`) instead.

## Prerequisites

- .NET 10 SDK
- `dotnet add package SquidStd.Caching` (and `SquidStd.Caching.Redis` for the Redis backend)
- For Redis: `docker run -p 6379:6379 redis`

## Steps

### 1. Register the in-memory cache

[!code-csharp[](../../samples/SquidStd.Samples.Caching/Program.cs#step-1)]

### 2. Set and get typed values

`ICacheService` stores typed values with an optional TTL; `GetAsync<T>` returns `null` on a miss.

[!code-csharp[](../../samples/SquidStd.Samples.Caching/Program.cs#step-2)]

### 3. Switch to Redis

Replace the registration with the Redis backend — the `ICacheService` usage is identical:

```csharp
container.AddRedisCache("redis://localhost:6379");
```

## Run it

```bash
dotnet run --project samples/SquidStd.Samples.Caching
```

Prints `hello`.

## How it works

`ICacheService` is the typed facade over an `ICacheProvider`; the provider is the swappable backend (in-memory or
Redis). Values are serialized with the shared `IDataSerializer`, so the same code works on either backend.

## See also

- [SquidStd.Caching reference](../articles/caching.md)
- [SquidStd.Caching.Redis reference](../articles/caching-redis.md)
52 changes: 52 additions & 0 deletions docs/tutorials/database.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Database (FreeSql + SQLite)

Persist a typed entity and read it back with paging, using SQLite with no external database.

## What you'll build

A host that registers the database subsystem (`SquidStd.Database`) and resolves the generic data access
`IDataAccess<TEntity>` (`SquidStd.Database.Abstractions`) to insert and page over a simple entity. It runs against a
local SQLite file out of the box.

## Prerequisites

- .NET 10 SDK
- `dotnet add package SquidStd.Database`
- No external database: the default connection string is `sqlite://squidstd.db`, and the schema is auto-migrated on
startup.

## Steps

### 1. Register the database service

`RegisterDatabase` wires the `database` config section, the `IDatabaseService` (which owns the FreeSql instance), and
the open-generic `IDataAccess<>`. Starting the bootstrap starts the database service and auto-creates the schema.

[!code-csharp[](../../samples/SquidStd.Samples.Database/Program.cs#step-1)]

### 2. Insert and page over an entity

Resolve `IDataAccess<Product>` for any `BaseEntity`-derived type. `InsertAsync` assigns the id and timestamps;
`GetPagedAsync` returns a `PagedResultData<T>` with items and paging metadata.

[!code-csharp[](../../samples/SquidStd.Samples.Database/Program.cs#step-2)]

## Run it

```bash
dotnet run --project samples/SquidStd.Samples.Database
```

Prints the two inserted products ordered by price, with the total count and page metadata.

## How it works

`IDatabaseService` builds a single FreeSql ORM from the URI-style connection string (the scheme selects the provider:
`sqlite`, `postgres`, `mysql`, `sqlserver`). `IDataAccess<TEntity>` is the generic repository over any
`BaseEntity`: it exposes CRUD, bulk operations, a composable `Query()` (FreeSql `ISelect`), and `GetPagedAsync` for
page + total-count reads. Every entity gets a `Guid` id plus UTC `Created`/`Updated` timestamps from `BaseEntity`.

## See also

- [SquidStd.Database reference](../articles/database.md)
- [SquidStd.Database.Abstractions reference](../articles/database-abstractions.md)
Loading
Loading