AyCode.Core/docs/CONVENTIONS.md

3.8 KiB

Conventions

Naming

  • Prefix: All framework types use Ac prefix (e.g., AcDalBase, AcBinarySerializer, AcLoggerBase).
  • Interfaces: Standard I prefix + Ac (e.g., IAcDbContextBase, IAcUserDbSetBase).
  • Extensions: {Domain}Extensions.cs (e.g., StringExtensions, CollectionExtensions, AcDbSessionExtension).
  • Test bases: Ac{Domain}TestBase or AcBase_{TestName} for inherited test methods.

Patterns

  • Extension methods over instance methods for CRUD operations. Keeps interfaces clean, implementations composable.
  • Session/Transaction pattern in DataLayers: Session() for reads, Transaction() for writes. Both are mutex-protected.
  • Generic interface hierarchy for entities: Interface → Abstract Entity → Concrete (in consuming project).
  • Partial classes for large serializers (AcBinarySerializer, AcToonSerializer split across 10+ files).
  • Source generation for hot-path serialization. Runtime reflection only as fallback.

Serialization Conventions

  • Binary serializer properties are written in alphabetical order (matches source generator output).
  • String interning is opt-in via [AcStringIntern] attribute or enableInternString flag.
  • Chain API for multi-type deserialization with cross-reference resolution.
  • Feature flags on [AcBinarySerializable] eliminate dead code from generated output.

SignalR Conventions

See SIGNALR_ARCHITECTURE.md for full architecture documentation.

  • Single dispatch method — all communication goes through OnReceiveMessage(int messageTag, byte[] messageBytes, int? requestId). Do not add new hub methods.
  • Tag-based routing — associate methods with integer tags via [SignalR(tag)] (server) or [SignalRSendToClient(tag)] (client). Tags must be unique across the entire system.
  • CRUD bundles — entities use SignalRCrudTags(baseTag) which allocates 5 sequential tags (GetAll, GetItem, Add, Update, Remove). Reserve non-overlapping base tags.
  • Binary protocolAcBinaryHubProtocol is the transport protocol. Responses use pure Binary serialization.

⚠️ Temporary: JSON-in-Binary Request Parameters

Client→server request parameters currently use a JSON→Binary→JSON round-trip:

  1. SignalPostJsonDataMessage<T> serializes PostData to JSON string (PostDataJson)
  2. The JSON-containing message is wrapped in a Binary envelope
  3. Server deserializes Binary → extracts JSON string → parses JSON per parameter

This is planned for replacement with direct Binary parameter serialization (matching how responses already work). Do not attempt to fix this as a side-effect of other work — it requires coordinated client+server+consuming-project changes.

Testing

  • MSTest framework across all test projects.
  • Abstract test bases with AcBase_ prefixed methods for reusable test logic.
  • TestDataFactory for centralized test data creation with ID sequencing.
  • Testable infrastructure for SignalR: TestableSignalRClient2, TestableSignalRHub2 bypass real connections.

Code Reuse

  • Before writing new code, search the codebase for existing implementations.
  • If a method does most of what you need, extract the shared part into a smaller reusable method rather than copying and modifying.
  • Prefer composing existing helpers over creating parallel implementations.
  • When adding a variation of existing logic, refactor the original into composable pieces that both call sites can use.

Critical Rules

  • Never modify PasswordHasher salt/iteration logic — breaks existing password verification.
  • Never renumber LogLevel enum values — synchronized with database.
  • Never fix "Finnished" spelling — intentional legacy typo in consuming projects.
  • Never suggest removal as a solution — find a fix instead.