Building the .NET AI App Foundation

A small ASP.NET Core foundation for model access, validated configuration, tracing, buffered and streaming HTTP contracts, and future AI capabilities.

September 20, 2026 · 11 min · Lukas Walter

Use DateTimeOffset for instants that cross system boundaries

Use DateTimeOffset for timestamps sent through APIs, messages, or storage when they must identify one unambiguous point in time.

September 20, 2026 · 3 min · Lukas Walter

Indexing Your First Documents

Index documents in Qdrant from .NET with Azure OpenAI or local Ollama embeddings, stable point IDs, useful payloads, and a read-back check.

September 16, 2026 · 12 min · Lukas Walter

nameof(List<>) works without a generic type argument in C# 14

C# 14 lets you write nameof(List<>) instead of supplying a type argument just to get the name. The result is still List.

September 12, 2026 · 2 min · Lukas Walter

Dependency Injection for AI Components

Register .NET AI clients, tools, prompts, and retrieval services with explicit lifetimes, safe request state, and clear disposal ownership.

September 9, 2026 · 10 min · Lukas Walter

Treat the model finish reason as a control signal

Check why generation stopped before accepting model output, and give incomplete responses an explicit application outcome.

September 9, 2026 · 2 min · Lukas Walter

Persist ingestion checkpoints at source boundaries

Track progress per consumer and source ordering boundary, and advance each checkpoint only after the corresponding ingestion work succeeds.

September 8, 2026 · 4 min · Lukas Walter

Treat provider throttling as a shared capacity signal

Let one throttling response reduce pressure from every caller sharing the affected capacity pool.

September 7, 2026 · 3 min · Lukas Walter

await foreach does not automatically use your cancellation token

A CancellationToken in scope does nothing unless the async enumeration receives and observes it.

September 6, 2026 · 2 min · Lukas Walter

Preserve the stack trace with throw, not throw ex

Rethrow the current exception with throw; so the original failure location remains visible.

September 5, 2026 · 2 min · Lukas Walter