A collection of NuGet utility libraries targeting net8.0, net9.0, and net10.0 simultaneously. See README.md for a high-level description.
dotnet build # build all projects
dotnet test # run xunit v3 tests (Sagara.Core.Tests)
dotnet pack # produce .nupkg / .snupkg artifacts
make_docs.bat # regenerate XML-doc → Markdown (requires Debug build first)All projects multi-target; avoid singling out a TFM unless fixing a framework-specific issue.
| Project | Purpose |
|---|---|
| Sagara.Core | Core utilities — guards, enums, extensions, I/O, JSON, time, validation |
| Sagara.Core.AspNetCore | ASP.NET Core filters, ModelState helpers, exception handling |
| Sagara.Core.Caching | Redis cache abstractions (StackExchange.Redis) |
| Sagara.Core.Data | EF Core data-access patterns |
| Sagara.Core.Logging.Serilog | Serilog bootstrapping & enrichment |
| Sagara.Core.Tests | xunit v3 unit tests for Sagara.Core |
| Sagara.Core.Benchmarks | BenchmarkDotNet harnesses (net10.0 only) |
Configured globally in Directory.Build.props:
- SDK: 10.0.203 (
global.json); C# 14; Implicit usings enabled. - Nullable reference types: enabled — always annotate parameters, returns, and fields.
- Analysis:
AllEnabledByDefault. CA1307, CA1309, CA1310 are treated as errors — always pass an explicitStringComparisonorCultureInfoargument. - Warnings as errors: keep the build clean; don't suppress without a comment explaining why.
- SourceLink + deterministic builds are configured — do not change
EmbedUntrackedSourcesor symbol settings.
Check.cs provides static guard methods. Prefer these over raw ArgumentNullException/ArgumentException:
Check.ThrowIfNull(value);
Check.ThrowIfNullOrWhiteSpace(name);
Check.ThrowIfEmptyGuid(id);[CallerArgumentExpression] is used automatically — do not pass the argument name manually.
Validation/ uses accumulator-style validation:
var errors = new List<RequestError>();
ValidationHelper.CheckRequiredField(errors, new ValidatableProperty<string>(value, "Display Name"));
if (errors.Count > 0) { /* fail */ }RequestError is a record struct (string PropertyName, string ErrorMessage).
EnumTraits<TEnum>— typed enum helper (name lookup, parse, validate).[InvalidEnumValue]attribute — marks sentinel values (e.g.,Unknown = 0) that must be rejected at boundaries.
SequentialGuid.GenerateComb() is [Obsolete] on .NET 9+; prefer Guid.CreateVersion7() there.
Use NodaTime types (Instant, LocalDate, etc.) via NodaTimeHelper. Avoid DateTime/DateTimeOffset in new code unless required by external APIs.
RedisCache and RedisAdminCache wrap StackExchange.Redis. Logging is via the injected ILogger; see RedisCacheLogger for log-level definitions.
API docs live under src/<Project>/docs/ and are generated from XML doc-comments via DefaultDocumentation.
Run make_docs.bat after a Debug build to regenerate them. Do not hand-edit the generated .md files.
Only nuget.org is configured (nuget.config). Do not add custom feeds without updating that file.