3.9 KiB
3.9 KiB
DTO System
Part of
Mango.Nop.Core. SeeMango.Nop.Core/README.mdfor project overview.
Two Mapping Strategies
Strategy 1: ModelDtoBase<T> (simple DTOs)
Used by: CustomerDto, MgGenericAttributeDto
ModelDtoBase → ModelDtoBase<Customer> → CustomerDto
- Manual
CopyEntityValuesToDto/CopyDtoValuesToEntityoverrides CreateMainEntity()usesActivator.CreateInstance<T>()- 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 value-type 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
Productfields
DTO Types
| Type | Generic params | Maps to entity | Key features |
|---|---|---|---|
ModelDtoBase |
— | — | Abstract base, int Id only |
ModelDtoBase<TMainEntity> |
TMainEntity : BaseEntity |
TMainEntity |
CreateMainEntity(), CopyEntityValuesToDto(), CopyDtoValuesToEntity() |
MgOrderDto<TOrderItemDto, TProductDto> |
TOrderItemDto : IMgOrderItemDto<TProductDto>, TProductDto : IMgProductDto |
Order |
Has Customer, List<TOrderItemDto>, List<OrderNote> navigations. Enum wrappers: OrderStatus, ShippingStatus, PaymentStatus |
MgOrderItemDto<TProductDto> |
TProductDto : IMgProductDto |
OrderItem |
Has TProductDto? navigation. Computed ProductName property |
MgProductDto |
— | (commented out) | Base product DTO. Name, Price, StockQuantity, dimensions. No entity mapping methods (currently commented out) |
MgGenericAttributeDto |
— | GenericAttribute |
Inherits GenericAttribute directly (not ModelDtoBase). Full bidirectional mapping |
MgStockQuantityHistoryDto<TProductDto> |
TProductDto : IMgProductDto |
StockQuantityHistory |
Has TProductDto navigation. Mapping methods NotImplementedException (stub) |
CustomerDto |
— | Customer |
Username, Email, FirstName, LastName, FullName computed. Uses [AcBinarySerializable] and LinqToDB [Table] |
DTO Interfaces
| Interface | Extends | Purpose |
|---|---|---|
IModelDtoBase |
IEntityInt, IModelDtoBaseEmpty |
Marker for all DTOs with int Id |
IModelDtoBase<TMainEntity> |
IModelDtoBase |
Bidirectional mapping contract: CreateMainEntity(), CopyDtoValuesToEntity(), CopyEntityValuesToDto() |
IMgOrderDto<TOrderItemDto, TProductDto> |
IEntityInt, ISoftDeletedEntity |
Order DTO contract with navigation properties and initialization methods |
IMgOrderItemDto<TProductDto> |
IEntityInt |
Order item DTO contract with product navigation |
IMgProductDto |
IEntityInt, ILocalizedEntity, ISlugSupported, IAclSupported, IStoreMappingSupported, ISoftDeletedEntity |
Product DTO contract |
GenericAttribute Typed Access
GenericAttributeExtensions provides typed access to nopCommerce's polymorphic key-value store:
| Method | Signature | Purpose |
|---|---|---|
GetValueOrNull<TValue> |
(IEnumerable<GenericAttribute>, string key) -> TValue? |
Get typed value, returns null if not found |
GetValueOrDefault<TValue> |
(IEnumerable<GenericAttribute>, string key, TValue default) -> TValue |
Same with default fallback |
TryGetValue<TValue> |
(IEnumerable<GenericAttribute>, string key, out TValue?) -> bool |
Try-pattern for GA value |
AddNewGenericAttribute |
(ICollection<GenericAttribute>, ...) -> GenericAttribute |
Create and add new GA with UTC timestamp |
Rule: Always use these extension methods — never parse GenericAttribute.Value strings manually.