Infrastructure Providers
Deepstaging infrastructure providers follow two canonical patterns depending on whether they integrate with a third-party API or provide persistence/hosting infrastructure.
Third-Party API Provider Pattern
Reference implementation: Stripe
Deepstaging.Payments.Stripe/
├── StripeConfig.cs — [ConfigSection] with [Secret] fields
├── StripeJsonContext.cs — STJ source-generated JSON context
├── StripePaymentsClient.cs — [HttpClient<StripeConfig>] partial class
├── StripeCustomersClient.cs — additional clients per API domain
├── StripeRegistration.cs — AddStripe<T>() DI extension
├── StripeAuthHandler.cs — DelegatingHandler for auth + API versioning
├── Models/ — response model records
├── Ids/ — TypedIds with provider-specific profile
└── Webhooks/ — IWebhookValidator + event types
Key Elements
| Element |
Pattern |
Purpose |
{Provider}Config |
[ConfigSection("Deepstaging:{Provider}")] |
Config with [Secret] for API keys |
{Provider}JsonContext |
[JsonSerializable] |
STJ source-generated serialization |
| HTTP clients |
[HttpClient<TConfig>] partial classes |
Generated typed clients with auth |
| Auth handler |
DelegatingHandler subclass |
Bearer token, API key, or basic auth |
| Registration |
Add{Provider}<T>(this T builder) |
DI registration extension method |
| TypedIds |
[TypedId(Profile = "{Provider}IdProfile")] |
Provider-specific ID format (e.g., cus_ prefix for Stripe) |
| Webhooks |
IWebhookValidator implementation |
Provider-specific signature validation |
Providers Following This Pattern
| Provider |
Package |
API Domain |
| Stripe |
Deepstaging.Payments.Stripe |
Payments, customers, invoices |
| Twilio |
Deepstaging.Twilio |
SMS, voice |
| Bandwidth |
Deepstaging.Bandwidth |
SMS, voice, messaging |
| Slack |
Deepstaging.Chat.Slack |
Chat, webhooks |
| Amazon SES |
Deepstaging.Ses |
Email sending |
Infrastructure Provider Pattern
Reference implementation: Postgres
Deepstaging.Data.Postgres/
├── Contexts/ — EF Core DbContext classes
├── DataStore/ — Per-entity store implementations
├── Identity/ — IIdentityStore implementation
├── Audit/ — IAuditStore implementation
├── Migrations/ — EF Core migrations
└── Registration/ — Feature-modular DI extensions
├── AddPostgresDataStore()
├── AddPostgresIdentity()
└── AddPostgresAudit()
Key Differences from API Providers
| Aspect |
API Provider |
Infrastructure Provider |
| Communication |
HTTP clients |
Direct SDK/DbContext |
| DI registration |
Single Add{Provider}() |
Feature-modular Add{Provider}{Feature}() |
| Configuration |
[ConfigSection] with [Secret] |
Connection strings, EF options |
| Service lifetime |
Singleton |
Scoped (per-request for DbContext) |
| Auth |
DelegatingHandler |
Connection string credentials |
Providers Following This Pattern
| Provider |
Package |
Infrastructure |
| Postgres |
Deepstaging.Data.Postgres |
EF Core persistence (DataStore, Identity, Audit) |
| Supabase |
Deepstaging.Supabase |
Supabase client (auth, storage, realtime) |
| Azure |
Deepstaging.Cloud.Azure |
Table storage, Service Bus, Functions |
| Marten |
Deepstaging.EventStore.Marten |
Event sourcing with Marten/PostgreSQL |
| Meilisearch |
Deepstaging.Search.Meilisearch |
Full-text search |
Creating a New Provider
- Choose the pattern: API provider (HTTP-based) or infrastructure provider (direct SDK)
- For API providers: Start with
[ConfigSection] + [HttpClient<TConfig>]; the generators handle client implementation, JSON serialization, effects, and test doubles
- For infrastructure providers: Create feature-modular DI extensions; implement the runtime interfaces (
IDataStore, IIdentityStore, etc.)
- Always include: Webhook validation if the provider sends webhooks, TypedIds for provider-specific identifiers