# Conventions ## Naming - **`Mg` prefix** for all custom types: `MgEntityBase`, `MgOrderDto`, `MgDbTableBase`, `MgDalBase`, etc. - **`I` + name** for interfaces: `IMgDalBase`, `IMgDbTableBase`, `IMgOrderDto`, `IMgLockService`. - **`Dto` suffix** for DTOs wrapping nopCommerce entities: `MgOrderDto`, `MgProductDto`, `MgOrderItemDto`. - **`DbTable` suffix** for repository classes: `MgDbTableBase`, `MgDtoDbTableBase`. - **`Base` suffix** for abstract base classes: `MgEntityBase`, `ModelDtoBase`, `MgBackgroundServiceBase`. - **`Nop` prefix** for nopCommerce bridge types: `NopLogWriter`, `NopLoggerMsSqlNopDataProvider`, `NopCommonConst`. ## XML Documentation `` — brief, developer-facing, readable in VS IntelliSense tooltip. NO implementation details, NO wire-format / byte-level / perf specifics — those live in `docs/TOPIC/*.md`. Add `` only when usage is non-obvious; otherwise omit. ## Patterns ### DTO Bidirectional Mapping - `ModelDtoBase` provides `CopyEntityValuesToDto(entity)`, `CopyDtoValuesToEntity(entity)`, and `CreateMainEntity()`. Override all three in concrete DTOs. - Simple DTOs (e.g. `CustomerDto`) — manual property-by-property copy in overrides. - Complex DTOs (e.g. `MgOrderDto`) — use `PropertyHelper.CopyPublicValueTypeProperties(source, target)` for automatic value-type property copy, then manually set reference/navigation properties. ### LinqToDB Associations - DTOs with navigation properties use `[Association(ThisKey, OtherKey, CanBeNull)]` from LinqToDB. - `ThisKey` = local FK property name, `OtherKey` = target entity property name (typically `Id` or via interface member like `nameof(IMgProductDto.Id)`). ### NopDependencies Mirror - Entity classes in `NopDependencies/` use the **same namespace** as the original nopCommerce types. Do not change namespaces. - All mirror classes are `partial` — they can be extended but should not be modified directly. ### GenericAttribute Typed Access - Use `GenericAttributeExtensions.GetValueOrDefault()` / `GetValueOrNull()` / `TryGetValue()` instead of raw string parsing. - Use `AddNewGenericAttribute()` to create new attributes with automatic UTC timestamp. ### Repository Base Chain - `MgDbTableBase` → `EntityRepository` (nopCommerce). Override virtual `OnInsert`/`OnUpdate`/`OnDelete` hooks, don't replace the chain. - `MgDtoDbTableBase` → `MgDbTableBase`. **Never call Delete directly** — always use `DeleteMainEntityById(int id)`. ### Timestamp Interfaces - Entities implementing `ITimeStampCreated` get `Created = DateTime.UtcNow` on insert. - Entities implementing `ITimeStampModified` get `Modified = DateTime.UtcNow` on insert and update. - `ITimeStampInfo` combines both (`Creator`, `Created`, `Modified`). ### Transaction Pattern - Use `MgDbContextBase.TransactionSafeAsync()` for operations needing global lock (order creation, stock adjustment). - Callback returns `bool` — `true` commits, `false` rolls back. - Exceptions are caught and logged by default (return `false`). Pass `throwException: true` only for fail-fast scenarios. ### Event Consumer Pattern - Inherit `MgEventConsumerBase` and override relevant `HandleEventAsync` methods. - Base class handles DI of `IMgDbContextBase`, `IHttpContextAccessor`, and `IAcLogWriterBase[]`. - Base provides `CheckAndUpdateProductManageInventoryMethodToManageStock(Product)` helper. ### Session Pattern - Inherit `MgSessionServiceBase` and `MgSessionItemBase`. - Sessions stored in `ConcurrentDictionary` — thread-safe, in-memory only. - Session items track `SessionId`, `SignaRConnectionId`, `RequestCount`. ### Logging - Base logging infrastructure (`IAcLoggerBase`, `IAcLogWriterBase`, `AcLoggerBase`, `AcLogItemWriterBase`) — see `AyCode.Core/AyCode.Core/docs/LOGGING/README.md`. - Services create loggers via `new Logger(logWriters.ToArray())` in constructor. - `logWriters` injected as `IEnumerable` — typically contains `NopLogWriter` + other writers. - **Exception:** `MgBackgroundServiceBase` uses `Nop.Services.Logging.ILogger` directly (nopCommerce logger), not the Mango wrapper. ### Serialization Attributes - `[ToonDescription(...)]` — AyCode metadata for AI/doc tooling. `Purpose`, `BusinessRule`, `TypeRelation`, `RelatedTypes` properties. - `[AcBinarySerializable(false, true, false, true, false)]` — AcBinarySerializer config (see `AyCode.Core/AyCode.Core/docs/BINARY/BINARY_FORMAT.md`). Parameters control serialization behavior for AcSignalR transport (see `AyCode.Core/AyCode.Services/docs/SIGNALR/README.md`). - LinqToDB `[Table(Name = "...")]` and `[Association(...)]` — DB mapping. ## Project Boundaries - `Mango.Nop.Core` — NO nopCommerce runtime dependency. Only NopDependencies mirrors. No `Nop.Data`, `Nop.Services` references. - `Mango.Nop.Data` — depends on nopCommerce data layer (`Nop.Core`, `Nop.Data`). No `Nop.Services` reference. - `Mango.Nop.Services` — depends on full nopCommerce stack (includes `Nop.Services`, `Nop.Web.Framework`). ## AyCode Integration Points Key AyCode types used across these libraries: - `IEntityInt` (AyCode.Interfaces.Entities) — `int Id` entity contract - `IBaseEntity` — defined locally in NopDependencies, mirrors AyCode's concept - `IAcLoggerBase`, `IAcLogWriterBase`, `AcLoggerBase`, `AcLogItemWriterBase` — logging infrastructure (see `AyCode.Core/AyCode.Core/docs/LOGGING/README.md`) - `IAcModelDtoBaseEmpty` — DTO marker interface - `IAcSoftRemoveEntity`, `IAcSoftRemoveEntityInt` — soft-delete contracts - `IForeignKey`, `IForeignCollection` — FK marker interfaces - `ITimeStampCreated`, `ITimeStampModified`, `ITimeStampInfo` — timestamp contracts - `PropertyHelper.CopyPublicValueTypeProperties()` — reflection-based property copy - `TaskHelper.ToThreadPoolTask()` — wraps async work in thread pool - `AcConst` — abstract constants base - `ToonDescription` — metadata attribute for AI tooling