[英]How to avoid services in DtoMappers layer
美好的一天,我有一個 Spring 基於引導的后端,我們正在使用自己的庫將 JPA 實體轉換為 Dto(庫基於反射工作)。 問題是,我們直接將服務層注入一些映射器。 假設我有一個UserEntity
和UserDto
。 UserDto 有一個名為 avatar 的字段,頭像存儲在S3
中。 因此,為了構建 UserDto,我們使用這樣的代碼。
@Component
class UserMapper {
@Inject
S3Service s3Service;
public UserDto toDto(UserEntity entity){
UserDto dto = new UserDto();
BeanUtils.copy(entity,dto);
dto.setAvatar(s3Service.getAvatarByUser(entity));
}
}
我不喜歡這種方法,因為 Mapper 一定對服務層一無所知。 然而,這個映射器也被其他映射器使用。 如果我想返回一個 OrderDto,它有一個嵌套的 UserDto,所以 OrderDto 在內部調用 UserMapper。 Mappers 是否有免費服務的最佳實踐?
到目前為止,我嘗試了以下方法。
ThreadLocal
緩存中。 controller調用service獲取用戶時,service會將用戶頭像保存在ThreadLocal中,然后Mapper從ThreadLocal緩存中獲取。 缺點 - 很難測試它並且需要我制作 MocksUserEntity entity;String avatar
,並為UserWithAvatar
而不是UserEntity
創建一個映射器。 缺點 - 正如我所說,這個映射器將由OrderMapper
使用,並且訂單映射器采用帶有嵌套UserEntity
而不是UserWithAvatar
的OrderEntity
我認為映射器應該在服務范圍內,但我會嘗試滿足您的要求
你有2個選擇:
您將服務和映射器都注入 controller,在返回響應之前使用映射器將實體返回到 controller 和 map
使用事件發布來發布一個事件,然后映射器捕獲並生成映射。 之后,您可以直接將 dto 返回到 controller 或產生另一個事件。 (事件發布默認是同步的,所以你不必擔心並發問題)
事件發布是通過 spring 完成的,並導致非常不耦合的代碼,其中發布者對事件訂閱者一無所知,因此這兩個可以在 2 個單獨的層中,彼此不知道任何事情
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.