如何创建从实体到嵌套 dto 的映射器?

How do I create a mapper from entity to dto, where dto is nested?

给出了两个对应dto的实体

实体:

class GalleryBlock(
    var images: List<Image?>,
    override val sortIndex: Int = 0,
) : ArticleBlock(sortIndex)

class Image(
    var url: String,
    var imageSize: ImageSize,
    override var id: Long,
    override var lastModified: Date,
    override var lastModifiedBy: String? = null ) : DBEntity

enum class ImageSize {
    SMALL,
    MEDIUM,
    LARGE, }

dtos

data class GalleryBlockDto(
    var images: List<ImageDto>,
    override val sortIndex: Int,
) : ArticleBlockDto

data class ImageDto(
    var id: Long,
    var url: String,
    var imageSize: ImageSize,
)

为了映射我写了一个接口Mapper

interface Mapper<E, D> {
    fun fromEntity(entity: E): D
}

为了从 class Image 到 ImageDto 的映射,我创建了一个 class ImageMapper

@Component
class ImageMapper: Mapper<Image, ImageDto> {
    override fun fromEntity(entity: Image): ImageDto {
        return ImageDto(entity.id, entity.url, entity.imageSize)
    }
}

在映射 GalleryBlock 时,我做了同样的事情,但我发现类型不匹配。

@Component
class GalleryBlockMapper: Mapper<GalleryBlock, GalleryBlockDto> {
    override fun fromEntity(entity: GalleryBlock): GalleryBlockDto {
        val images = entity.images
        val sortIndex = entity.sortIndex
        return GalleryBlockDto(images, sortIndex)
    }
}

我的做法正确吗?以及如何在不更改 Dto 和实体字段的情况下修复类型不匹配问题?

在 GalleryBlockMapper 中,您将 Image 实例传递给 GalleryBlockDto。但是需要 ImageDto 实例。 GalleryBlockMapper需要注入ImageMapper,才能映射图片

@Component
class GalleryBlockMapper(private val imageMapper: ImageMapper): Mapper<GalleryBlock, GalleryBlockDto> {
    override fun fromEntity(entity: GalleryBlock): GalleryBlockDto {
        val images = entity.images.map { imageMapper.fromEntity(it) }
        val sortIndex = entity.sortIndex
        return GalleryBlockDto(images, sortIndex)
    }
}