# Mango.Nop Libraries — Domain Rules @repo { type = "framework" layer = 1 own-dep-repos = ["AyCode.Core"] } > This is the **single source of truth** for Mango.Nop library rules. Do not duplicate these elsewhere. > For detailed docs see: `README.md` → `docs/` > For core framework rules see: `.github/copilot-instructions.md` (in AyCode.Core repo) ## nopCommerce Compatibility 1. All three libraries target **net9.0** — required by nopCommerce 4.80.9. Do NOT change TFM. 2. **NopDependencies** folder in `Mango.Nop.Core` contains **mirror copies** of nopCommerce entity classes (`BaseEntity`, `Customer`, `Order`, `Product`, `GenericAttribute`, etc.) so that `Mango.Nop.Core` can be referenced without the full nopCommerce dependency chain. 3. Do NOT modify files in `NopDependencies/` unless the nopCommerce version changes. ## Entity & DTO Patterns 4. **`BaseEntity`** (NopDependencies) = root entity base with `int Id` and `IBaseEntity` interface. All nopCommerce entities inherit from this. Namespace: `Nop.Core`. 5. **`MgEntityBase`** = custom entity base that inherits `BaseEntity` and implements `IEntityInt` (from AyCode.Interfaces). Used for domain-specific entities and complex DTOs. 6. **Two DTO base strategies exist:** - `ModelDtoBase` — for simple DTOs (e.g. `CustomerDto`). Manual `CopyEntityValuesToDto`/`CopyDtoValuesToEntity` overrides. Uses `Activator.CreateInstance()` in `CreateMainEntity()`. - `MgEntityBase` + `IModelDtoBase` — for complex DTOs with LinqToDB `[Association]` navigations (e.g. `MgOrderDto`, `MgOrderItemDto`). Uses `PropertyHelper.CopyPublicValueTypeProperties()` for automatic value-type copy. 7. **`GenericAttribute`** = polymorphic key-value store. `KeyGroup` = owner type name, `EntityId` = owner ID, `Key` = attribute name, `Value` = string value. Use `GenericAttributeExtensions.GetValueOrNull()`/`GetValueOrDefault()`/`TryGetValue()` — never parse raw strings manually. ## Data Access Patterns 8. **`MgDbTableBase`** = repository base wrapping nopCommerce `EntityRepository`. Adds `GetAll()` (`IQueryable`), automatic timestamp handling (`ITimeStampCreated`/`ITimeStampModified`), virtual CRUD hooks (`OnInsert`/`OnUpdate`/`OnDelete`). 9. **`MgDtoDbTableBase`** = DTO-aware repository. **CRITICAL: All Delete methods throw — always use `DeleteMainEntityById(int id)`.** Event bridging: DTO insert/update events → main entity events. 10. **`MgDbContextBase`** = DB context base (NOT EF Core DbContext — wraps `INopDataProvider` and `IRepository` nopCommerce repos). Provides `Transaction`/`TransactionSafe`/`TransactionAsync`/`TransactionSafeAsync`. TransactionSafe variants use global `SemaphoreSlim` lock for serialized access. ## Service Patterns 11. **`MgBackgroundServiceBase`** — inherits `Microsoft.Extensions.Hosting.BackgroundService`. Loop: `Task.Delay(interval)` → `OnExecuteAsync()`. Pause support. Per-iteration exception handling. **Uses nopCommerce `Nop.Services.Logging.ILogger`** (not Mango logger). 12. **`MgEventConsumerBase`** — subscribes to `EntityUpdatedEvent`, `EntityInsertedEvent`, `CustomerRegisteredEvent`, `OrderPlacedEvent`, `PageRenderingEvent`, `ProductSearchEvent`. Override relevant handlers. Built-in: `CheckAndUpdateProductManageInventoryMethodToManageStock()`. 13. **`NopLogWriter`** — AyCode → nopCommerce log bridge. Log level mapping: `Detail/Trace/Debug/Info` → `Information`; `Suggest/Warning` → `Warning`; `Error` → `Error`. Uses `TransactionScope(Suppress)` to avoid nesting. ## Conventions 14. **`Mg` prefix** for all custom types: `MgEntityBase`, `MgOrderDto`, `MgDbTableBase`, etc. 15. **No redundant code** — before writing new logic, check whether similar methods already exist in the current context. Reuse or extract shared logic. 16. **Keep all .md files in sync** — when you modify code and you know which .md file documents it, update that .md file too. If you notice a contradiction between code and an .md file, automatically update the .md to match the code (code is the source of truth). When fixing a reference, check other .md files that may share the same broken reference. If the root cause is at a lower layer, fix it there first. During code review, if you find useful behavior or conventions not yet documented, briefly suggest what to document and where — but do not add new content without approval. 17. All AyCode references are via **DLL** (not ProjectReference) — this is intentional. Types not defined in this library (e.g. `IEntityInt`, `IId`, `AcConst`, `ToonDescription`) likely live in AyCode.Core. DLL HintPaths in .csproj point to the correct relative location. 18. **Documentation layering** — write `.md` documentation at the **defining layer** (where the code lives). Higher-layer `.md` files reference AyCode.Core base docs using the form `AyCode.Core/{Project}/docs/FILENAME.md` (resolved via rule 17 base path). Document only project-specific overrides or extensions. Never duplicate base-layer descriptions in consumer-level docs. 19. **LinqToDB associations** — use `[Association(ThisKey = nameof(FK), OtherKey = nameof(Target.Id), CanBeNull = true/false)]` for navigation properties in DTOs. 20. **Timestamp auto-management** — entities with `ITimeStampCreated` or `ITimeStampModified` get automatic UTC timestamps in `MgDbTableBase` CRUD hooks. Don't set these manually. ## Reference Modes - **Full stack** (ProjectReference, all 3 libraries) — for nopCommerce plugins needing entity access, data layer, and services. - **Types only** (DLL reference, `Mango.Nop.Core` only) — for projects that only need DTOs, entities, and interfaces without the nopCommerce runtime dependency.