Mango.Nop.Libraries/docs/ARCHITECTURE.md

7.2 KiB

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<TMainEntity> 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<TEntity> — extends nopCommerce EntityRepository<TEntity>, adds GetAll(), timestamp handling (ITimeStampCreated, ITimeStampModified), event publishing
  • MgDtoDbTableBase<TDtoEntity, TMainEntity> — 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<TDbContext> — 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<TSessionItem> / MgSessionItemBase — in-memory session management via ConcurrentDictionary, SignalR connection tracking
  • MgEventConsumerBase — nopCommerce entity event handler base (Product insert/update, CustomerRegistered, OrderPlaced, PageRendering, ProductSearch)
  • MgLockServiceBaseSemaphoreSlim(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:

// 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<T> (simple DTOs)

Used by: CustomerDto, MgGenericAttributeDto

ModelDtoBase → ModelDtoBase<Customer> → CustomerDto
  • Manual CopyEntityValuesToDto/CopyDtoValuesToEntity overrides
  • No LinqToDB associations

Strategy 2: MgEntityBase + IModelDtoBase<T> (complex DTOs)

Used by: MgOrderDto, MgOrderItemDto, MgStockQuantityHistoryDto

BaseEntity → MgEntityBase → MgOrderDto<TOrderItemDto, TProductDto> : IModelDtoBase<Order>
  • 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<Product> (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<TransactionScope, (Task<)bool(>)> — 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<TCategory> (extends AcLoggerBase, delegates to IAcLogWriterBase[])
                        → NopLogWriter (in Services, extends AcLogItemWriterBase<AcLogItem>) → 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)