Skip to content

Commit 904e676

Browse files
committed
merge: DocFX tutorials + runnable samples for all SquidStd libraries
2 parents 2d33a68 + ce7bc0b commit 904e676

48 files changed

Lines changed: 1745 additions & 1 deletion

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

SquidStd.slnx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,22 @@
2929
<Project Path="src/SquidStd.Mail.MailKit/SquidStd.Mail.MailKit.csproj"/>
3030
<Project Path="src/SquidStd.Mail.Queue/SquidStd.Mail.Queue.csproj"/>
3131
</Folder>
32+
<Folder Name="/samples/">
33+
<Project Path="samples/SquidStd.Samples.WorkerSystem/SquidStd.Samples.WorkerSystem.csproj" />
34+
<Project Path="samples/SquidStd.Samples.Templating/SquidStd.Samples.Templating.csproj" />
35+
<Project Path="samples/SquidStd.Samples.Storage/SquidStd.Samples.Storage.csproj" />
36+
<Project Path="samples/SquidStd.Samples.Search/SquidStd.Samples.Search.csproj" />
37+
<Project Path="samples/SquidStd.Samples.ScriptingLua/SquidStd.Samples.ScriptingLua.csproj" />
38+
<Project Path="samples/SquidStd.Samples.Plugins/SquidStd.Samples.Plugins.csproj" />
39+
<Project Path="samples/SquidStd.Samples.Networking/SquidStd.Samples.Networking.csproj" />
40+
<Project Path="samples/SquidStd.Samples.Email/SquidStd.Samples.Email.csproj" />
41+
<Project Path="samples/SquidStd.Samples.Database/SquidStd.Samples.Database.csproj" />
42+
<Project Path="samples/SquidStd.Samples.AspNetCore/SquidStd.Samples.AspNetCore.csproj" />
43+
<Project Path="samples/SquidStd.Samples.Messaging/SquidStd.Samples.Messaging.csproj" />
44+
<Project Path="samples/SquidStd.Samples.Caching/SquidStd.Samples.Caching.csproj" />
45+
<Project Path="samples/SquidStd.Samples.EventsJobsScheduling/SquidStd.Samples.EventsJobsScheduling.csproj" />
46+
<Project Path="samples/SquidStd.Samples.GettingStarted/SquidStd.Samples.GettingStarted.csproj" />
47+
</Folder>
3248
<Folder Name="/tests/">
3349
<Project Path="tests/SquidStd.Tests/SquidStd.Tests.csproj"/>
3450
</Folder>

docs/docfx.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"build": {
1616
"content": [
1717
{ "files": [ "api/**.{yml,md}" ] },
18-
{ "files": [ "articles/**.{md,yml}", "*.md", "toc.yml" ] }
18+
{ "files": [ "articles/**.{md,yml}", "tutorials/**.{md,yml}", "*.md", "toc.yml" ] }
1919
],
2020
"resource": [
2121
{ "files": [ "images/**" ] }

docs/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,7 @@
22
href: index.md
33
- name: Articles
44
href: articles/
5+
- name: Tutorials
6+
href: tutorials/
57
- name: API
68
href: api/

docs/tutorials/aspnetcore-app.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Host SquidStd in an ASP.NET Core app
2+
3+
Wire SquidStd into an ASP.NET Core Minimal API and expose its health checks over HTTP.
4+
5+
## What you'll build
6+
7+
A Minimal API web app that uses SquidStd (`SquidStd.AspNetCore`) as its DryIoc-backed service provider, surfaces
8+
the registered SquidStd health checks at `/health`, and answers a simple root endpoint.
9+
10+
## Prerequisites
11+
12+
- .NET 10 SDK
13+
- `dotnet add package SquidStd.AspNetCore`
14+
15+
## Steps
16+
17+
### 1. Register SquidStd on the builder
18+
19+
`UseSquidStd` swaps in DryIoc as the ASP.NET Core service provider and bootstraps SquidStd. The root directory is
20+
taken from the host environment automatically, so you only set the config name.
21+
22+
[!code-csharp[](../../samples/SquidStd.Samples.AspNetCore/Program.cs#step-1)]
23+
24+
### 2. Bridge the health checks
25+
26+
`AddSquidStdHealthChecks` registers every SquidStd `IHealthCheck` as a standard ASP.NET Core health check. Call it
27+
after `UseSquidStd`.
28+
29+
[!code-csharp[](../../samples/SquidStd.Samples.AspNetCore/Program.cs#step-2)]
30+
31+
### 3. Build the app and map endpoints
32+
33+
Build the app, expose the health checks with the standard `MapHealthChecks`, add a root endpoint, and run.
34+
35+
[!code-csharp[](../../samples/SquidStd.Samples.AspNetCore/Program.cs#step-3)]
36+
37+
## Run it
38+
39+
```bash
40+
dotnet run --project samples/SquidStd.Samples.AspNetCore
41+
```
42+
43+
Browse to `/` for the "SquidStd up" message and to `/health` for the aggregated health-check status.
44+
45+
## How it works
46+
47+
`UseSquidStd` creates an owned DryIoc container, registers it through `DryIocServiceProviderFactory`, and hooks the
48+
SquidStd lifecycle into the ASP.NET Core host via a hosted service. `AddSquidStdHealthChecks` resolves the SquidStd
49+
`IHealthCheck` instances from that container and adapts each one into the standard health-check pipeline, so
50+
`MapHealthChecks` reports them like any other ASP.NET Core check.
51+
52+
## See also
53+
54+
- [SquidStd.AspNetCore reference](../articles/aspnetcore.md)
55+
- Previous: [Getting started](getting-started.md)

docs/tutorials/caching.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Caching (in-memory + Redis)
2+
3+
Cache typed values with a TTL, then swap the in-memory backend for Redis without changing your code.
4+
5+
## What you'll build
6+
7+
A host that resolves `ICacheService` (`SquidStd.Caching.Abstractions`) backed by the in-memory provider
8+
(`SquidStd.Caching`), and the one-line change to use Redis (`SquidStd.Caching.Redis`) instead.
9+
10+
## Prerequisites
11+
12+
- .NET 10 SDK
13+
- `dotnet add package SquidStd.Caching` (and `SquidStd.Caching.Redis` for the Redis backend)
14+
- For Redis: `docker run -p 6379:6379 redis`
15+
16+
## Steps
17+
18+
### 1. Register the in-memory cache
19+
20+
[!code-csharp[](../../samples/SquidStd.Samples.Caching/Program.cs#step-1)]
21+
22+
### 2. Set and get typed values
23+
24+
`ICacheService` stores typed values with an optional TTL; `GetAsync<T>` returns `null` on a miss.
25+
26+
[!code-csharp[](../../samples/SquidStd.Samples.Caching/Program.cs#step-2)]
27+
28+
### 3. Switch to Redis
29+
30+
Replace the registration with the Redis backend — the `ICacheService` usage is identical:
31+
32+
```csharp
33+
container.AddRedisCache("redis://localhost:6379");
34+
```
35+
36+
## Run it
37+
38+
```bash
39+
dotnet run --project samples/SquidStd.Samples.Caching
40+
```
41+
42+
Prints `hello`.
43+
44+
## How it works
45+
46+
`ICacheService` is the typed facade over an `ICacheProvider`; the provider is the swappable backend (in-memory or
47+
Redis). Values are serialized with the shared `IDataSerializer`, so the same code works on either backend.
48+
49+
## See also
50+
51+
- [SquidStd.Caching reference](../articles/caching.md)
52+
- [SquidStd.Caching.Redis reference](../articles/caching-redis.md)

docs/tutorials/database.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Database (FreeSql + SQLite)
2+
3+
Persist a typed entity and read it back with paging, using SQLite with no external database.
4+
5+
## What you'll build
6+
7+
A host that registers the database subsystem (`SquidStd.Database`) and resolves the generic data access
8+
`IDataAccess<TEntity>` (`SquidStd.Database.Abstractions`) to insert and page over a simple entity. It runs against a
9+
local SQLite file out of the box.
10+
11+
## Prerequisites
12+
13+
- .NET 10 SDK
14+
- `dotnet add package SquidStd.Database`
15+
- No external database: the default connection string is `sqlite://squidstd.db`, and the schema is auto-migrated on
16+
startup.
17+
18+
## Steps
19+
20+
### 1. Register the database service
21+
22+
`RegisterDatabase` wires the `database` config section, the `IDatabaseService` (which owns the FreeSql instance), and
23+
the open-generic `IDataAccess<>`. Starting the bootstrap starts the database service and auto-creates the schema.
24+
25+
[!code-csharp[](../../samples/SquidStd.Samples.Database/Program.cs#step-1)]
26+
27+
### 2. Insert and page over an entity
28+
29+
Resolve `IDataAccess<Product>` for any `BaseEntity`-derived type. `InsertAsync` assigns the id and timestamps;
30+
`GetPagedAsync` returns a `PagedResultData<T>` with items and paging metadata.
31+
32+
[!code-csharp[](../../samples/SquidStd.Samples.Database/Program.cs#step-2)]
33+
34+
## Run it
35+
36+
```bash
37+
dotnet run --project samples/SquidStd.Samples.Database
38+
```
39+
40+
Prints the two inserted products ordered by price, with the total count and page metadata.
41+
42+
## How it works
43+
44+
`IDatabaseService` builds a single FreeSql ORM from the URI-style connection string (the scheme selects the provider:
45+
`sqlite`, `postgres`, `mysql`, `sqlserver`). `IDataAccess<TEntity>` is the generic repository over any
46+
`BaseEntity`: it exposes CRUD, bulk operations, a composable `Query()` (FreeSql `ISelect`), and `GetPagedAsync` for
47+
page + total-count reads. Every entity gets a `Guid` id plus UTC `Created`/`Updated` timestamps from `BaseEntity`.
48+
49+
## See also
50+
51+
- [SquidStd.Database reference](../articles/database.md)
52+
- [SquidStd.Database.Abstractions reference](../articles/database-abstractions.md)

docs/tutorials/email.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Email: receive, send, and queue
2+
3+
Poll a mailbox for inbound mail, send outbound mail over SMTP, and queue mail for background delivery.
4+
5+
## What you'll build
6+
7+
A host using `SquidStd.Mail.MailKit` and `SquidStd.Mail.Queue`: an IMAP poller that raises a `MailReceivedEvent`
8+
for each new email, an SMTP sender (`IMailSender`), and a fire-and-forget send queue (`IMailQueue`) backed by
9+
messaging. The contracts live in `SquidStd.Mail.Abstractions`.
10+
11+
## Prerequisites
12+
13+
- .NET 10 SDK
14+
- `dotnet add package SquidStd.Mail.MailKit`
15+
- `dotnet add package SquidStd.Mail.Queue`
16+
- Real IMAP/SMTP credentials are only needed to actually connect; the sample compiles and runs without them.
17+
18+
## Steps
19+
20+
### 1. Receive: poll a mailbox
21+
22+
`AddMail` registers an IMAP/POP3 poller; each received message is published as a `MailReceivedEvent`, which an
23+
`IAsyncEventListener<MailReceivedEvent>` handles.
24+
25+
[!code-csharp[](../../samples/SquidStd.Samples.Email/Program.cs#step-1)]
26+
27+
### 2. Send: outbound SMTP
28+
29+
`AddMailSender` registers `IMailSender`; build an `OutgoingMailMessage` and call `SendAsync`.
30+
31+
[!code-csharp[](../../samples/SquidStd.Samples.Email/Program.cs#step-2)]
32+
33+
### 3. Queue: background delivery
34+
35+
`AddInMemoryMessaging` plus `AddMailQueue` register `IMailQueue`; `EnqueueAsync` hands the message to a
36+
background consumer that sends it via the SMTP sender.
37+
38+
[!code-csharp[](../../samples/SquidStd.Samples.Email/Program.cs#step-3)]
39+
40+
## Run it
41+
42+
```bash
43+
dotnet run --project samples/SquidStd.Samples.Email
44+
```
45+
46+
It registers the poller, sender, and queue, registers the received-mail listener, and enqueues a message.
47+
Pass `--send` to also attempt a synchronous SMTP send (requires a reachable server).
48+
49+
## How it works
50+
51+
The poller runs on the timer wheel, fetches new messages over IMAP/POP3 with MailKit, and publishes a
52+
`MailReceivedEvent` on the event bus. `IMailSender` maps `OutgoingMailMessage` to a MIME message and sends it.
53+
`AddMailQueue` layers a queue over `SquidStd.Messaging`: `EnqueueAsync` publishes to the queue and a background
54+
consumer (`MailSendConsumerService`) drains it through `IMailSender`, decoupling request latency from delivery.
55+
56+
## See also
57+
58+
- [SquidStd.Mail.MailKit reference](../articles/mail-mailkit.md)
59+
- [SquidStd.Mail.Queue reference](../articles/mail-queue.md)
60+
- [SquidStd.Mail.Abstractions reference](../articles/mail-abstractions.md)
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Events, jobs and scheduling
2+
3+
Publish in-process events, run work on a thread pool, and schedule recurring jobs with cron.
4+
5+
## What you'll build
6+
7+
A host that uses three core services from `SquidStd.Services.Core`: the `IEventBus` (publish/subscribe), the
8+
`IJobSystem` (thread-pool work), and the `ICronScheduler` (cron-based recurring jobs).
9+
10+
## Prerequisites
11+
12+
- .NET 10 SDK
13+
- `dotnet add package SquidStd.Services.Core`
14+
15+
The cron scheduler and timer wheel are opt-in — enable them with `RegisterSchedulerServices()`:
16+
17+
[!code-csharp[](../../samples/SquidStd.Samples.EventsJobsScheduling/Program.cs#step-1)]
18+
19+
## Steps
20+
21+
### 1. Publish and handle an event
22+
23+
Implement `IAsyncEventListener<T>`, register it, and publish an `IEvent`. Every registered listener is awaited.
24+
25+
[!code-csharp[](../../samples/SquidStd.Samples.EventsJobsScheduling/Program.cs#step-1)]
26+
27+
### 2. Run work on the job system
28+
29+
`IJobSystem.ScheduleAsync` runs an `Action` on a worker thread and returns a `Task` that completes when it finishes.
30+
31+
[!code-csharp[](../../samples/SquidStd.Samples.EventsJobsScheduling/Program.cs#step-2)]
32+
33+
### 3. Schedule a cron job
34+
35+
`ICronScheduler.Schedule` takes a name, a 5-field cron expression (UTC), and an async handler invoked on each
36+
occurrence.
37+
38+
[!code-csharp[](../../samples/SquidStd.Samples.EventsJobsScheduling/Program.cs#step-3)]
39+
40+
## Run it
41+
42+
```bash
43+
dotnet run --project samples/SquidStd.Samples.EventsJobsScheduling
44+
```
45+
46+
You'll see `received: hello`, `job ran on a worker thread`, and—if you let it run across a 5-minute boundary—
47+
`cron tick`.
48+
49+
## How it works
50+
51+
The event bus dispatches to sync and async listeners; the job system is a fixed-size worker-thread pool; the cron
52+
scheduler is driven by the timer wheel (registered by `RegisterSchedulerServices`).
53+
54+
## See also
55+
56+
- [SquidStd.Services.Core reference](../articles/services-core.md)
57+
- [SquidStd.Core reference](../articles/core.md)
58+
- Previous: [Getting started](getting-started.md)

docs/tutorials/getting-started.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Getting started: your first SquidStd host
2+
3+
Build a minimal SquidStd application: a bootstrapper that loads config, configures logging, and runs the
4+
registered services until shutdown.
5+
6+
## What you'll build
7+
8+
A console host on top of `SquidStdBootstrap` (from `SquidStd.Services.Core`, which brings in `SquidStd.Core`
9+
and `SquidStd.Abstractions`). It loads its config, wires the default services, and runs until you stop it.
10+
11+
## Prerequisites
12+
13+
- .NET 10 SDK
14+
- `dotnet add package SquidStd.Services.Core`
15+
16+
## Steps
17+
18+
### 1. Create the bootstrapper
19+
20+
`SquidStdBootstrap.Create` takes a `SquidStdOptions` (config name + root directory) and registers the core
21+
services (config, logging, event bus, jobs, timers…) into an owned DryIoc container.
22+
23+
[!code-csharp[](../../samples/SquidStd.Samples.GettingStarted/Program.cs#step-1)]
24+
25+
### 2. Start the services
26+
27+
`StartAsync` starts every registered `ISquidStdService` in priority order.
28+
29+
[!code-csharp[](../../samples/SquidStd.Samples.GettingStarted/Program.cs#step-2)]
30+
31+
### 3. Run until shutdown
32+
33+
`RunAsync` starts (if not already started), waits for cancellation, then stops the services cleanly. Use either
34+
`StartAsync` plus your own loop, or just `RunAsync`.
35+
36+
[!code-csharp[](../../samples/SquidStd.Samples.GettingStarted/Program.cs#step-3)]
37+
38+
## Run it
39+
40+
```bash
41+
dotnet run --project samples/SquidStd.Samples.GettingStarted
42+
```
43+
44+
The host starts, logs the service lifecycle, and waits until you press Ctrl+C.
45+
46+
## How it works
47+
48+
`SquidStdBootstrap` is the composition root: it builds the container, registers the core services, loads the
49+
config sections, and orchestrates the `ISquidStdService` lifecycle. Every other SquidStd module plugs into this
50+
container through its `Add…` extension methods.
51+
52+
## See also
53+
54+
- [SquidStd.Services.Core reference](../articles/services-core.md)
55+
- [SquidStd.Core reference](../articles/core.md)
56+
- Next: [Events, jobs and scheduling](events-jobs-scheduling.md)

0 commit comments

Comments
 (0)