# Architecture ## Dependency Graph ``` AyCode.Core (net9.0, DLL refs: AyCode.Interfaces, .Entities, .Core, .Utils, + .Server variants) ↑ Mango.Nop.Core (net9.0, no nopCommerce runtime dependency) ↑ Mango.Nop.Data (net9.0) → Nop.Core, Nop.Data ↑ Mango.Nop.Services (net9.0) → Nop.Core, Nop.Data, Nop.Services, Nop.Web.Framework ``` **Rule:** Dependencies flow upward only. `Mango.Nop.Core` has zero nopCommerce runtime dependency — it uses mirror copies in `NopDependencies/`. ## Project Roles ### Mango.Nop.Core — Domain Layer Zero nopCommerce runtime dependency. Contains: - **DTOs** (`Dtos/`) — `ModelDtoBase` with bidirectional entity mapping (`CopyEntityValuesToDto`, `CopyDtoValuesToEntity`, `CreateMainEntity`) - **Entities** (`Entities/`) — `MgEntityBase` (inherits `BaseEntity`, implements `IEntityInt`) - **NopDependencies** (`NopDependencies/`) — mirror copies of nopCommerce entities (`BaseEntity`, `Customer`, `Order`, `Product`, `GenericAttribute`, enums). Allows referencing without full nopCommerce dependency chain. - **Extensions** (`Extensions/`) — `GenericAttributeExtensions` for typed attribute access, `CollectionExtensionsNopBaseEntity` for collection operations - **Interfaces** (`Interfaces/`) — DTO interfaces, soft-delete, foreign key markers - **Models** (`Models/`) — Login request/response - **Loggers** (`Loggers/`) — `ILogger` abstraction wrapping AyCode `IAcLoggerBase` ### Mango.Nop.Data — Data Access Layer Wraps nopCommerce data infrastructure with custom base classes: - **`MgDbTableBase`** — extends nopCommerce `EntityRepository`, adds `GetAll()`, timestamp handling (`ITimeStampCreated`, `ITimeStampModified`), event publishing - **`MgDtoDbTableBase`** — DTO-aware repository. **Critical: Delete operations throw — must use `DeleteMainEntityById()`.** Event bridging: DTO events → main entity events - **`MgDbContextBase`** — DB context base with `Transaction/TransactionSafe/TransactionAsync/TransactionSafeAsync` methods. TransactionSafe variants use global `SemaphoreSlim` lock - **`MgDalBase`** — Data Access Layer orchestrator with `Context`, `Name`, `MutextLock` ### Mango.Nop.Services — Service Layer Service base classes for nopCommerce plugin development: - **`MgBackgroundServiceBase`** — hosted background task with configurable interval, pause support, per-iteration error handling - **`MgSessionServiceBase`** / `MgSessionItemBase` — in-memory session management via `ConcurrentDictionary`, SignalR connection tracking - **`MgEventConsumerBase`** — nopCommerce entity event handler base (Product insert/update, CustomerRegistered, OrderPlaced, PageRendering, ProductSearch) - **`MgLockServiceBase`** — `SemaphoreSlim(1)` lock wrapper - **`NopLogWriter`** — logging bridge: AyCode log levels → nopCommerce `Log` table via direct DB insert with `TransactionScope(Suppress)` ## NopDependencies Pattern `Mango.Nop.Core/NopDependencies/` contains mirror copies of nopCommerce entity classes with the **same namespace** as the original nopCommerce types: ```csharp // In NopDependencies/BaseEntity.cs — same namespace as nopCommerce namespace Nop.Core; public abstract partial class BaseEntity : IBaseEntity { public int Id { get; set; } } ``` This allows `Mango.Nop.Core` to be referenced by projects that don't have a direct nopCommerce dependency (e.g., Blazor/MAUI clients), while maintaining type compatibility with the real nopCommerce entities at the server level. **Files in NopDependencies:** - `BaseEntity.cs` + `IBaseEntity` — root entity base (`Nop.Core`) - `Catalogs/` — `Customer`, `CustomerRole`, `Order`, `OrderItem`, `OrderNote`, `Product`, `GenericAttribute`, `StockQuantityHistory`, `DiscountMapping`, `DiscountProductMapping` - Enums — `OrderStatus`, `PaymentStatus`, `ShippingStatus`, `ProductType`, `ManageInventoryMethod`, `BackorderMode`, `LowStockActivity`, `GiftCardType`, `RentalPricePeriod`, `RecurringProductCyclePeriod`, `DownloadActivationType`, `TaxDisplayType`, `VatNumberStatus` - Interfaces — `ISoftDeletedEntity`, `ILocalizedEntity`, `ISlugSupported`, `IAclSupported`, `IStoreMappingSupported`, `IDiscountSupported` ## DTO Mapping Strategies Two patterns coexist: ### Strategy 1: `ModelDtoBase` (simple DTOs) Used by: `CustomerDto`, `MgGenericAttributeDto` ``` ModelDtoBase → ModelDtoBase → CustomerDto ``` - Manual `CopyEntityValuesToDto`/`CopyDtoValuesToEntity` overrides - No LinqToDB associations ### Strategy 2: `MgEntityBase` + `IModelDtoBase` (complex DTOs) Used by: `MgOrderDto`, `MgOrderItemDto`, `MgStockQuantityHistoryDto` ``` BaseEntity → MgEntityBase → MgOrderDto : IModelDtoBase ``` - Uses `PropertyHelper.CopyPublicValueTypeProperties()` for bulk copy - LinqToDB `[Association]` navigation properties - Generic type parameters for child DTOs ### Strategy 3: Entity inheritance (MgProductDto) ``` BaseEntity → MgEntityBase → MgProductDto : IMgProductDto ``` - No `IModelDtoBase` (entity mapping methods are commented out) - Direct property declarations mirroring `Product` fields ## Transaction Pattern `MgDbContextBase` provides 4 transaction methods: | Method | Lock | Async | |---|---|---| | `Transaction(callback)` | No | No | | `TransactionSafe(callback)` | `SemaphoreSlim` | No | | `TransactionAsync(callback)` | No | Yes (thread pool) | | `TransactionSafeAsync(callback)` | `SemaphoreSlim` | Yes (thread pool) | **Callback contract:** `Func)>` — return `true` to commit, `false` to rollback. **Isolation level:** `ReadCommitted` **Error handling:** Catches exceptions, logs, returns `false` (unless `throwException = true`) ## Logging Architecture Base logging infrastructure (`IAcLoggerBase`, `IAcLogWriterBase`, `AcLoggerBase`, `AcLogItemWriterBase`, `AcLogItem`) is defined in AyCode.Core — see `AyCode.Core/docs/LOGGING.md` for base types, log levels, and writer contracts. This layer provides the nopCommerce-specific bridge: ``` Application code → Mango.Nop.Core.Loggers.ILogger (extends IAcLoggerBase) → Logger (extends AcLoggerBase, delegates to IAcLogWriterBase[]) → NopLogWriter (in Services, extends AcLogItemWriterBase) → Nop Log table (direct SQL insert) → [Other AyCode log writers: console, file, SignalR, etc. — see AyCode.Core/docs/LOGGING.md] ``` **Important:** `MgBackgroundServiceBase` uses nopCommerce's `Nop.Services.Logging.ILogger` directly (not the Mango wrapper). Other services use `Mango.Nop.Core.Loggers.ILogger`. ## Reference Modes ``` Mango.Nop Libraries ┌──────────────────────┐ │ Core Data Services │ └──┬──────┬──────┬─────┘ │ │ │ ┌───────────────┤ │ │ │ (DLL, Core │ │ │ │ only) │ │ │ ▼ ▼ ▼ ▼ Types-only clients Full-stack nopCommerce (Blazor/MAUI/etc.) plugins (server-side) ```