بنقرة واحدة
koan-multi-provider
Provider transparency, capability detection, context routing (partition/source/adapter)
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Provider transparency, capability detection, context routing (partition/source/adapter)
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
Auto-registration via KoanAutoRegistrar, minimal Program.cs, "Reference = Intent" pattern
Chat endpoints, embeddings, RAG workflows, vector search
Aggregate boundaries, relationships, lifecycle hooks, value objects
Entity<T> patterns, GUID v7 auto-generation, static methods vs manual repositories
Transparent L1/L2 caching for Entity<T>, [Cacheable] attribute, cross-node coherence, per-request opt-out
Run a mandatory pre-implementation exploration workflow before writing production code in Koan (.NET/C#). Use when a task requires code changes and Codex must first map concerns/layers, read relevant files and docs, check existing constants and types, identify the closest existing pattern, plan exact code placement, and confirm architectural guardrails.
استنادا إلى تصنيف SOC المهني
| name | koan-multi-provider |
| description | Provider transparency, capability detection, context routing (partition/source/adapter) |
Same entity code works across SQL, NoSQL, Vector, JSON stores. Koan Framework provides complete provider transparency with automatic capability detection and graceful fallbacks.
Write code once, run on any data provider:
No code changes needed to switch providers. Just change configuration.
// Check what current provider supports
var capabilities = Data<Todo, string>.QueryCaps;
if (capabilities.Capabilities.HasFlag(QueryCapabilities.LinqQueries))
{
// Provider supports server-side LINQ (Postgres, Mongo, SQL Server)
var filtered = await Todo.Query(t => t.Priority > 3 && !t.Completed);
}
else
{
// Provider requires client-side filtering (JSON, InMemory)
var all = await Todo.All();
var filtered = all.Where(t => t.Priority > 3 && !t.Completed).ToList();
}
// Check fast removal support
if (Todo.SupportsFastRemove)
{
// Provider supports TRUNCATE/DROP (Postgres, SQL Server, Mongo)
await Todo.RemoveAll(RemoveStrategy.Fast);
}
Partitions provide logical data isolation within same provider:
// Default partition
var todo = new Todo { Title = "Active task" };
await todo.Save(); // Stored as Todo
// Archive partition
using (EntityContext.Partition("archive"))
{
var archived = new Todo { Title = "Archived task" };
await archived.Save(); // Stored as Todo#archive
}
// Tenant isolation
using (EntityContext.Partition($"tenant-{tenantId}"))
{
var tenantTodos = await Todo.All(); // Only this tenant's data
}
Use Cases:
Sources route to different provider configurations:
// appsettings.json
{
"Koan": {
"Data": {
"Sources": {
"Default": {
"Adapter": "postgres",
"ConnectionString": "Host=localhost;Database=main"
},
"Analytics": {
"Adapter": "postgres",
"ConnectionString": "Host=readonly-replica;Database=analytics"
},
"Cache": {
"Adapter": "redis",
"ConnectionString": "localhost:6379"
}
}
}
}
}
// Route to analytics read-replica
using (EntityContext.Source("analytics"))
{
var stats = await Todo.Count; // Reads from replica
}
// Route to cache
using (EntityContext.Source("cache"))
{
var frequent = await FrequentQuery.Get(id); // From Redis
}
Use Cases:
Adapters explicitly select provider regardless of configuration:
// Force MongoDB
using (EntityContext.Adapter("mongodb"))
{
var todos = await Todo.All(); // Always uses MongoDB
}
// Force JSON for testing
using (EntityContext.Adapter("json"))
{
await todo.Save(); // Writes to JSON file
}
Use Cases:
NEVER combine Source and Adapter (ADR DATA-0077):
// ❌ WRONG: Conflicting context
using (EntityContext.Source("analytics"))
using (EntityContext.Adapter("mongodb"))
{
// Which wins? Undefined behavior!
}
// ✅ CORRECT: Use one or the other
using (EntityContext.Source("analytics"))
{
// Routes via named source configuration
}
// OR
using (EntityContext.Adapter("mongodb"))
{
// Explicit provider override
}
Contexts nest and replace previous values:
// Outer context
using (EntityContext.Source("analytics"))
{
var count1 = await Todo.Count; // analytics source
// Inner context replaces outer
using (EntityContext.Partition("archive"))
{
var count2 = await Todo.Count; // analytics + archive partition
}
var count3 = await Todo.Count; // back to analytics (no partition)
}
Use [DataAdapter] attribute to pin entity to provider:
// Always use MongoDB for this entity
[DataAdapter("mongodb")]
public class FlexibleDocument : Entity<FlexibleDocument>
{
public Dictionary<string, object> Properties { get; set; } = new();
}
// Always use vector database
[DataAdapter("weaviate")]
public class MediaEmbedding : Entity<MediaEmbedding>
{
[VectorField]
public float[] Embedding { get; set; } = Array.Empty<float>();
}
public async Task<List<Todo>> SearchWithFallback(string searchTerm)
{
var caps = Data<Todo, string>.QueryCaps;
if (caps.Capabilities.HasFlag(QueryCapabilities.FullTextSearch))
{
// Provider supports full-text search
return await Todo.Query($"CONTAINS(Title, '{searchTerm}')");
}
else
{
// Fallback to client-side filtering
var all = await Todo.All();
return all.Where(t => t.Title.Contains(searchTerm,
StringComparison.OrdinalIgnoreCase)).ToList();
}
}
| Provider | LINQ Queries | Transactions | Fast Remove | Vector Search | JSON Fields |
|---|---|---|---|---|---|
| PostgreSQL | ✅ | ✅ | ✅ | ✅ (pgvector) | ✅ |
| SQL Server | ✅ | ✅ | ✅ | ❌ | ✅ (limited) |
| MongoDB | ✅ | ✅ | ✅ | ❌ | ✅ (native) |
| SQLite | ✅ | ✅ | ✅ | ❌ | ✅ (json1) |
| Redis | ❌ | ❌ | ✅ | ❌ | ✅ |
| JSON | ❌ | ❌ | ❌ | ❌ | ✅ (native) |
| InMemory | ❌ | ❌ | ❌ | ❌ | ✅ |
| Weaviate | ❌ | ❌ | ❌ | ✅ | ✅ |
| Milvus | ❌ | ❌ | ❌ | ✅ | ✅ |
Invoke this skill when:
docs/guides/entity-capabilities-howto.md § Context Routingsamples/S10.DevPortal/ (Multi-provider showcase)samples/S14.AdapterBench/ (Provider performance comparison)Multi-provider patterns are fundamental to Koan Framework: