Mango.Nop.Libraries/docs/CONVENTIONS.md

86 lines
5.6 KiB
Markdown

# 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`.
## Patterns
### DTO Bidirectional Mapping
- `ModelDtoBase<TMainEntity>` 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<T>()` / `GetValueOrNull<T>()` / `TryGetValue<T>()` instead of raw string parsing.
- Use `AddNewGenericAttribute()` to create new attributes with automatic UTC timestamp.
### Repository Base Chain
- `MgDbTableBase<TEntity>``EntityRepository<TEntity>` (nopCommerce). Override virtual `OnInsert`/`OnUpdate`/`OnDelete` hooks, don't replace the chain.
- `MgDtoDbTableBase<TDtoEntity, TMainEntity>``MgDbTableBase<TDtoEntity>`. **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<TSessionItem>` and `MgSessionItemBase`.
- Sessions stored in `ConcurrentDictionary<string, TSessionItem>` — 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<TCategory>(logWriters.ToArray())` in constructor.
- `logWriters` injected as `IEnumerable<IAcLogWriterBase>` — 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)]` — 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<T>` — 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