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 就可以直接使用正确的构造函数。
我创建了一个域实体,所有设置方法都是私有的,因为它们在设置数据之前进行了一些验证。
所以我有 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 就可以直接使用正确的构造函数。