Sora.Storage
0.4.0
dotnet add package Sora.Storage --version 0.4.0
NuGet\Install-Package Sora.Storage -Version 0.4.0
<PackageReference Include="Sora.Storage" Version="0.4.0" />
<PackageVersion Include="Sora.Storage" Version="0.4.0" />
<PackageReference Include="Sora.Storage" />
paket add Sora.Storage --version 0.4.0
#r "nuget: Sora.Storage, 0.4.0"
#:package Sora.Storage@0.4.0
#addin nuget:?package=Sora.Storage&version=0.4.0
#tool nuget:?package=Sora.Storage&version=0.4.0
Sora.Storage
Storage orchestrator for Sora apps. Simple, profile-based routing with first-class DX to create, read, probe, copy, move, and delete objects across providers.
What it does
- Routing: Resolves profile → provider+container using options or rules with safe defaults.
- Orchestration: Streams data and computes SHA-256 for seekable uploads; supports range reads.
- Capabilities: Leverages provider features like server-side copy; presign when available.
- DX: Small, async helpers without Async suffix and a model-centric API for clean calls.
Setup
- Registration: Packages auto-register via the framework pipeline. Call
AppBootstrapper.InitializeModules(services)
once. Providers (e.g., Local) self-register. - Core options:
Sora:Storage:Profiles:<name>
→{ Provider, Container }
Sora:Storage:DefaultProfile
→ string (optional)Sora:Storage:FallbackMode
→Disabled | SingleProfileOnly | NamedDefault
(defaultSingleProfileOnly
)Sora:Storage:ValidateOnStart
→bool
(defaulttrue
)
Notes
- Ambient DI: APIs resolve
IStorageService
fromAppHost.Current
. In app host, this is set during startup (built into Sora templates).
Model‑centric API (recommended)
Bind a model type to a profile (and optionally a default container) and use concise statics/instance ops.
// Bind to profile "hot" (container optional; provider+container resolve via options)
[Sora.Storage.Infrastructure.StorageBinding("hot")]
public sealed class FileA : Sora.Storage.Model.StorageEntity<FileA> { }
[Sora.Storage.Infrastructure.StorageBinding("cold")]
public sealed class FileB : Sora.Storage.Model.StorageEntity<FileB> { }
// Create → Read → Copy/Move
var rec = await FileA.CreateTextFile("name.txt", "hello");
var text = await FileA.Get(rec.Key).ReadAllText();
await FileA.Get(rec.Key).CopyTo<FileB>();
await FileA.Get(rec.Key).MoveTo<FileB>();
// Other instance ops
var bytes = await FileA.Get(rec.Key).ReadAllBytes();
var head = await FileA.Get(rec.Key).Head(); // ObjectStat
Contract
- Inputs:
key
, optionalname
, content (string
/byte[]
/Stream
/ object for JSON), optionalcontentType
. - Outputs:
IStorageObject
with metadata (Id
,Key
,Name
,ContentType
,Size
,ContentHash
,CreatedAt
,UpdatedAt
,Provider
,Container
,Tags
). - Errors: Unknown profile/container → throws; missing key →
null
forHead
,false
forDelete
; invalid range → throws. Hash computed only on seekable streams.
Service helpers (alternative)
The same primitives are available directly on IStorageService
.
await storage.CreateTextFile("doc.txt", "hello", profile: "main");
var text = await storage.ReadAllText("main", "", "doc.txt");
var stat = await storage.HeadAsync("main", "", "doc.txt");
await storage.CopyTo("hot", "", "doc.txt", "cold");
Behavioral notes and edge cases
- Defaults and fallbacks: If profile is omitted,
DefaultProfile
is used when set; with exactly one profile,SingleProfileOnly
fallback applies. - Validation: With
ValidateOnStart=true
, misconfigurations fail fast during app start. - Large payloads: Use
ReadRangeAsString
/ReadRangeAsync
to avoid loading entire content. - Capabilities: Local provider supports lightweight stat and server-side copy; presign is unsupported.
References
- Reference:
docs/reference/storage.md
- Decisions:
STOR-0001
,STOR-0006
,STOR-0007
,DATA-0061
,ARCH-0040
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net9.0
- Microsoft.Extensions.DependencyInjection (>= 9.0.8)
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.8)
- Microsoft.Extensions.Options (>= 9.0.8)
- Newtonsoft.Json (>= 13.0.3)
- Sora.Core (>= 0.4.0)
- Sora.Data.Abstractions (>= 0.4.0)
- Sora.Data.Core (>= 0.4.0)
NuGet packages (4)
Showing the top 4 NuGet packages that depend on Sora.Storage:
Package | Downloads |
---|---|
Sora.Media.Abstractions
Media contracts for Sora: models, transforms, tasks, and events. |
|
Sora.Media.Core
Media core for Sora: Ensure, pipelines, ancestry, and URL helpers over Sora.Storage. |
|
Sora.Media.Web
Package Description |
|
Sora.Storage.Local
Local file-system storage provider for Sora. |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last Updated |
---|---|---|
0.4.0 | 80 | 9/5/2025 |
See release notes: https://github.com/sylin-labs/sora-framework/releases