1 主要概念:业务逻辑,领域逻辑
DDD聚焦于业务,业务逻辑落地到代码,主要关注两层,Application Layer和Domain Layer。 分别对应着测试用例(use cases)和领域逻辑(domian logic)。
2 DDD概念在分层架构中的落地
虚线箭头和理论有所区别,因为webapi层实际在解决方案中还承担着host的作用。
Domain
- Aggregate & Aggregate Root 聚合与聚合根
- Entity 实体
- Value Object 值对象
- Repository Interface 仓储接口
- Domain Service 领域服务
- Domain Event 领域事件
- Factory 工厂
主要的业务逻辑,包括实体,值对象,仓储接口等,复杂逻辑可添加领域服务。
public class Order : IAggregateRoot
{
public int OrderId { get; set; }
public string OrderCode { get; set; }
internal Order(string orderCode)
{
if (string.IsNullOrEmpty(orderCode))
{
throw new OrderException("OrderCode should have value!");
}
OrderCode = orderCode;
}
public Weight Weight { get; set; }
public List<OrderItem> OrderItems { get; set; } = new List<OrderItem>();
public int TotalAmount
{
get
{
return OrderItems.Sum(i => i.Amount);
}
}
public int CreatedBy { get; set; }
public DateTimeOffset CreatedTime { get; set; } = DateTimeOffset.Now;
public void AddOrderItem(OrderItem orderItem)
{
OrderItems.Add(orderItem);
}
}
Application
- Application Service 应用服务
- Data Transfer Object (DTO)
- Unit of Work 工作单元
包含Contracts,Mappers和Application services,基于Domain层实现用例逻辑。
public async Task<OrderDto> CreateAsync(OrderCreationDto orderCreationDto)
{
var order = await orderManager.CreateAsync(orderCreationDto.OrderCode);
order.OrderItems = orderCreationDto.OrderItems.Select(i => new Domain.Order.OrderItem(i.CommodityId, i.CommodityName, i.Amount)).ToList();
order.CreatedBy = orderCreationDto.CreatedBy;
order.Weight = orderCreationDto.Weight;
var savedOrder = await _orderRepository.InsertAsync(order);
order.OrderId = savedOrder.OrderId;
await distributedEventBus.PublishAsync(_mapper.Map<OrderChangedEto>(order));
return _mapper.Map<OrderDto>(order);
}
Use auto object mapping only for Entity to output DTO mappings.
Infrastructure
- Repository 仓储服务
接口的具体实现,比如持久化数据库,发送Event等。
public class KafkaEventBus : IDistributedEventBus
{
public Task PublishAsync<T>(T message)
{
throw new NotImplementedException();
}
}
API
- Controller
很薄的一层,主要负责依赖注入和控制器,使用Dto和Application层交互。
[HttpPost]
public async Task<ActionResult> CreateAsync(OrderCreationDto orderCreationDto)
{
_logger.LogInformation("Create {@orderCreationDto}", orderCreationDto);
await _orderService.CreateAsync(orderCreationDto);
return Ok();
}
3 典型的解决方案文件结构
📁 API
OrderController
📁 Application
OrderService / CreateOrderCommandHandler
📁 DomainEventHandlers
CreateOrderDomainEventHandler
📁 Contracts
CreateOrderRequest / CreateOrderCommand
CreateOrderResponse
📁 Domain
📁 OrderAggregate
Order: Entity, IAggregateRoot
OrderItem
OrderManager
Address : ValueObject
IOrderRepository
📁 Events
OrderCreatedDomainEvent
📁 Exception
OrderDomainException
📁 SeedWork
Entity
ValueObject
IAggregateRoot
📁 Domain.Shared
📁 Enums
OrderType
📁 Infrastructure
📁 Repositories
OrderRepository