System Architecture
Struktural is engineered as a high-performance, container-ready application built on .NET 10. Its architecture is strictly decoupled, separating the runtime execution engine from the tenant-specific metadata definitions (JSON and C# scripts).
Core Components
1. Kestrel Web Server & Middleware Pipeline
The entry point is a standard ASP.NET Core Kestrel server. Requests are intercepted by the AppIdentificationMiddleware, which determines the target tenant (AppId) for the current request. Once the tenant is identified, the pipeline injects the corresponding StrukturalRuntimeContext containing the compiled code and schema for that specific application.
2. Roslyn Dynamic Compiler (IDynamicCompiler)
When a tenant application is loaded (or hot-reloaded), the engine reads the JSON schemas and raw .cs.script files from the tenant's workspace. It utilizes the Microsoft Roslyn Compiler to generate Plain Old CLR Objects (POCOs) and compile the business logic into an in-memory Dynamic Link Library (DLL).
- AssemblyLoadContexts (ALC): To ensure isolated execution and prevent memory leaks during hot-reloads, each tenant's compiled assembly is loaded into a dedicated, collectible
StrukturalAssemblyLoadContext. When an application is updated, the old context is marked for unloading, allowing the Garbage Collector to free the memory.
3. Dynamic Entity Framework Core (StrukturalDynamicDbContext)
Struktural does not use a static DbContext. Instead, it instantiates a generic StrukturalDynamicDbContext at runtime.
- Model Cache Key Factory: To support multi-tenancy where multiple tenants might have an entity named
Invoicebut with entirely different schemas, Struktural overrides the EF CoreIModelCacheKeyFactory. This ensures EF Core maintains separate, isolated query caches and model definitions for each tenant. - Idempotent Migrations: Schema synchronizations are handled automatically by dialect-specific providers (
PostgresSchemaProvider,SqlServerSchemaProvider,OracleSchemaProvider). The platform calculates the diff between the JSON schema and the physical database snapshot to generate safe DDL statements.
4. Background Event Bus
Asynchronous workflows and system events (like ACL propagation) run outside the HTTP request lifecycle. Depending on the configuration, the Event Bus uses memory channels, database polling, or Apache Kafka to distribute messages to worker nodes.