3.0 KiB
3.0 KiB
Architecture
Dependency Graph
AyCode.Utils (zero dependencies)
↑
AyCode.Interfaces → AyCode.Entities → AyCode.Models
↑ ↑ ↑
AyCode.Core ─────────────┘ │
↑ │
AyCode.Database ────────────────────────────┘
↑
AyCode.Services ← AyCode.Services.Server
Rule: Dependencies flow upward only. Lower layers never reference higher layers.
Project Roles
Foundation Layer
- AyCode.Utils — Zero-dependency utilities. String/DateTime extensions, lock wrappers.
- AyCode.Interfaces — Pure interfaces.
IId<T>is the root abstraction. - AyCode.Entities — Abstract generic entity classes. Never instantiated directly.
- AyCode.Models — DTOs and view models for service boundaries.
Core Layer
- AyCode.Core — Serializers (Binary, JSON, Toon), compression (Brotli, GZip, LZ4), logging framework, constants, validation.
- AyCode.Core.Serializers.SourceGenerator — Roslyn incremental generator. Targets netstandard2.0. Generates
IGeneratedBinaryWriter/IGeneratedBinaryReaderfor[AcBinarySerializable]types.
Data Layer
- AyCode.Database — EF Core with generic DAL pattern. Session for reads, Transaction for writes. DAL pooling via
PooledDal.
Service Layer
- AyCode.Services — Client-side: SignalR client, login service, loggers.
- AyCode.Services.Server — Server-side: SignalR hub with custom binary protocol, email (SendGrid), JWT auth.
- AyCode.Models.Server/DynamicMethods — Reflection-based tag→method dispatch used by the SignalR hub.
SignalR Dispatch: Both directions use a single method
OnReceiveMessage(int messageTag, int? requestId, SignalParams signalParams, SignalData data)with integer tag-based routing instead of standard Hub methods.SignalDatawrapsArrayPool-backed byte buffers for zero-alloc receive path. SeeAyCode.Services/docs/SIGNALR.mdfor full details.
Server Extensions
- AyCode.Core.Server, AyCode.Interfaces.Server, AyCode.Entities.Server, AyCode.Models.Server — Server-only additions that don't belong in shared code.
Serialization Architecture
Three serializers share a common infrastructure but serve different goals:
| Serializer | Primary Goal | Use Case |
|---|---|---|
| AcBinary | Speed | Wire protocol, SignalR, storage |
| AcJson | Compatibility | REST APIs, debugging, interop |
| Toon | LLM Accuracy | AI context, schema documentation |
Generic Entity Pattern
Entities use composition via generic type parameters:
// Interface layer
interface IAcUser<TProfile, TCompany> : IId<Guid> { ... }
// Entity layer (abstract)
abstract class AcUser<TProfile, TCompany, TUserToCompany, TAddress> { ... }
// Consuming project (concrete)
class User : AcUser<Profile, Company, UserToCompany, Address> { ... }
This allows the framework to define relationships without knowing concrete types.