Automapper -> DTO to Entity - 如何在映射时触发 Setter 验证

Automapper -> DTO to Entity - How to trigger Setter validations when mapping

我创建了一个域实体,所有设置方法都是私有的,因为它们在设置数据之前进行了一些验证。

所以我有 Dtos 来交换数据,然后将它映射到实体,这样如果一切顺利,我就可以持久保存到数据库中。

当将 Dto 映射到实体时,我得到了填充了所有属性的实体,但没有执行 SetXXX,因为如果我直接调用构造函数就会发生这种情况。

使用 AutoMapper 时,对于这些情况,最佳或正确的方法是什么?

域实体

public Product(Guid id, ... decimal originalPrice, decimal discountedPrice...) :
            base(id)
        {
            OriginalPrice = CheckOriginalPrice(originalPrice, discountedPrice);
            DiscountedPrice = CheckDiscountedPrice(originalPrice, discountedPrice);
        }

        public virtual void SetOriginalPrice(decimal originalPrice, decimal discountedPrice)
        {
            OriginalPrice = CheckOriginalPrice(originalPrice, discountedPrice);
        }

private static decimal CheckOriginalPrice(decimal originalPrice, decimal discountedPrice)
        {
            if (originalPrice < 0)
                throw new ArgumentOutOfRangeException($"original price ({originalPrice} cannot be negative");
            else if (originalPrice < discountedPrice)
                throw new ArgumentOutOfRangeException($"original price ({originalPrice}) can not be lower than discounted price ({discountedPrice})!");

            return originalPrice;
        }

如果我这样做 Map 会成功,所以没有验证发生,如何触发构造函数?

var product = _objectMapper.Map<CreateProductDto, Product>(product);

如果我直接测试实体 class,它会在检查价格时通过测试,我得到异常。

var exception = await Assert.ThrowsAsync<ArgumentOutOfRangeException>(async () =>
            {
                //Act
                var product =
                    new Product(
                        _guidGenerator.Create(),
                        ...
                        4.05m,
                        8.05m,
                        ...
                    );
            });
            //Assert
            exception.Message.ShouldContain("original price");

那么,当使用 ObjetMapper.Map 进行映射时,构造函数将正确执行,我该如何实现,有没有简单的方法来实现它?

AutoMapper 有一个称为条件映射的功能,这似乎是您要找的:https://docs.automapper.org/en/stable/Conditional-mapping.html

我实际上设法通过使用与我的 dto 具有相同参数的构造函数来解决我的问题,这样 AutoMapper 就可以直接使用正确的构造函数。