6.4 KiB
6.4 KiB
Mango.Nop Libraries — Domain Rules
own-dep-repos: "name: path" — paths are relative to this repo root (.github/..)
@repo { name = "Mango.Nop Libraries" type = "framework" layer = 1 own-dep-repos = ["AyCode.Core: ../../../../../Aycode/Source/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) External repos inown-dep-reposare fully accessible — read their source code, docs, and.github/copilot-instructions.mdfreely when you need type definitions, base classes, or context. Do not limit yourself to the current workspace.
nopCommerce Compatibility
- All three libraries target net9.0 — required by nopCommerce 4.80.9. Do NOT change TFM.
- NopDependencies folder in
Mango.Nop.Corecontains mirror copies of nopCommerce entity classes (BaseEntity,Customer,Order,Product,GenericAttribute, etc.) so thatMango.Nop.Corecan be referenced without the full nopCommerce dependency chain. - Do NOT modify files in
NopDependencies/unless the nopCommerce version changes.
Entity & DTO Patterns
BaseEntity(NopDependencies) = root entity base withint IdandIBaseEntityinterface. All nopCommerce entities inherit from this. Namespace:Nop.Core.MgEntityBase= custom entity base that inheritsBaseEntityand implementsIEntityInt(from AyCode.Interfaces). Used for domain-specific entities and complex DTOs.- Two DTO base strategies exist:
ModelDtoBase<TMainEntity>— for simple DTOs (e.g.CustomerDto). ManualCopyEntityValuesToDto/CopyDtoValuesToEntityoverrides. UsesActivator.CreateInstance<T>()inCreateMainEntity().MgEntityBase+IModelDtoBase<T>— for complex DTOs with LinqToDB[Association]navigations (e.g.MgOrderDto,MgOrderItemDto). UsesPropertyHelper.CopyPublicValueTypeProperties()for automatic value-type copy.
GenericAttribute= polymorphic key-value store.KeyGroup= owner type name,EntityId= owner ID,Key= attribute name,Value= string value. UseGenericAttributeExtensions.GetValueOrNull<T>()/GetValueOrDefault<T>()/TryGetValue<T>()— never parse raw strings manually.
Data Access Patterns
MgDbTableBase<TEntity>= repository base wrapping nopCommerceEntityRepository<TEntity>. AddsGetAll()(IQueryable<T>), automatic timestamp handling (ITimeStampCreated/ITimeStampModified), virtual CRUD hooks (OnInsert/OnUpdate/OnDelete).MgDtoDbTableBase<TDtoEntity, TMainEntity>= DTO-aware repository. CRITICAL: All Delete methods throw — always useDeleteMainEntityById(int id). Event bridging: DTO insert/update events → main entity events.MgDbContextBase= DB context base (NOT EF Core DbContext — wrapsINopDataProviderandIRepository<T>nopCommerce repos). ProvidesTransaction/TransactionSafe/TransactionAsync/TransactionSafeAsync. TransactionSafe variants use globalSemaphoreSlimlock for serialized access.
Service Patterns
MgBackgroundServiceBase— inheritsMicrosoft.Extensions.Hosting.BackgroundService. Loop:Task.Delay(interval)→OnExecuteAsync(). Pause support. Per-iteration exception handling. Uses nopCommerceNop.Services.Logging.ILogger(not Mango logger).MgEventConsumerBase— subscribes toEntityUpdatedEvent<Product>,EntityInsertedEvent<Product>,CustomerRegisteredEvent,OrderPlacedEvent,PageRenderingEvent,ProductSearchEvent. Override relevant handlers. Built-in:CheckAndUpdateProductManageInventoryMethodToManageStock().NopLogWriter— AyCode → nopCommerce log bridge. Log level mapping:Detail/Trace/Debug/Info→Information;Suggest/Warning→Warning;Error→Error. UsesTransactionScope(Suppress)to avoid nesting.
Conventions
Mgprefix for all custom types:MgEntityBase,MgOrderDto,MgDbTableBase, etc.- No redundant code — before writing new logic, check whether similar methods already exist in the current context. Reuse or extract shared logic.
- 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.
- All AyCode references are via DLL (not ProjectReference) — this is intentional. AyCode.Core solution (
../../../../../Aycode/Source/AyCode.Core/) contains all core framework code: interfaces, serialization, binary protocol, SignalR base classes, data sources, logging. Types not defined in this library (e.g.IEntityInt,IId<T>,AcConst,ToonDescription) likely live in AyCode.Core. - Do not re-read .md files already in your context window. They only change if you modify them yourself (new content is already in context) or if the developer tells you they changed — in that case re-read them once.
- Documentation layering — write
.mddocumentation at the defining layer (where the code lives). Higher-layer.mdfiles reference AyCode.Core base docs using the form../../../../../Aycode/Source/AyCode.Core/{Project}/docs/FILENAME.md. Document only project-specific overrides or extensions. Never duplicate base-layer descriptions in consumer-level docs. - LinqToDB associations — use
[Association(ThisKey = nameof(FK), OtherKey = nameof(Target.Id), CanBeNull = true/false)]for navigation properties in DTOs. - Timestamp auto-management — entities with
ITimeStampCreatedorITimeStampModifiedget automatic UTC timestamps inMgDbTableBaseCRUD 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.Coreonly) — for projects that only need DTOs, entities, and interfaces without the nopCommerce runtime dependency.