简体   繁体   中英

AutoMapper: Avoid infinite recursion with MaxDepth?

I've the following simple code

    public class User
    {
        public List<UserGroup> UserGroups { get; set; }
        public string Name { get; set; }
    }

    public class UserGroup
    {
        public User User { get; set; }
        public Group Group { get; set; }
    }

    public class Group
    {
        public List<UserGroup> UserGroups { get; set; }
        public string Name { get; set; }
    }

    public class UserDto
    {
        public List<UserGroupDto> UserGroups { get; set; }
        public string Name { get; set; }
    }

    public class UserGroupDto
    {
        public UserDto User { get; set; }
        public GroupDto Group { get; set; }
    }

    public class GroupDto
    {
        public List<UserGroupDto> UserGroups { get; set; }
        public string Name { get; set; }
    }

    private static void TestAutoMapper()
    {
        var mapperCfg = new AutoMapper.MapperConfiguration(cfg =>
        {
            cfg.CreateMap<User, UserDto>().MaxDepth(1);
            cfg.CreateMap<UserGroup, UserGroupDto>().MaxDepth(1);
            cfg.CreateMap<Group, GroupDto>().MaxDepth(1);
        });
        var mapper = mapperCfg.CreateMapper();

        var user = new User { Name = "User1" };
        var group = new Group { Name = "Group1" };
        var userGroups = new List<UserGroup> { new UserGroup { User = user, Group = group } };
        user.UserGroups = userGroups;
        group.UserGroups = userGroups;

        var users = new List<User> { user };
        var usersDto = mapper.Map<IEnumerable<User>, IEnumerable<UserDto>>(users);
    }

But I can't prevent infinite recursion because it preserve the objects reference.

How can I limit to only the first "already mapped" instance?

example:

UserDto -> List -> UserGrop -> List (null)

UserDto -> List -> UserDto (null)

Thanks in advance.

Ok, it seems to be a bad pattern implementation.

I found a solution to my problem by adopting the following mappings.

    private static void TestAutoMapper()
    {
        var mapperCfg = new AutoMapper.MapperConfiguration(cfg =>
        {
            cfg.CreateMap<User, UserDto>()
                .ForMember(dst => dst.UserGroups, opt => opt.Ignore())
            ;
            cfg.CreateMap<UserGroup, UserGroupDto>();
            cfg.CreateMap<Group, GroupDto>()
                .ForMember(dst => dst.UserGroups, opt => opt.Ignore())
            ;
        });
        var mapper = mapperCfg.CreateMapper();

        var user = new User { Name = "User1" };
        var group = new Group { Name = "Group1" };
        var userGroups = new List<UserGroup> { new UserGroup { User = user, Group = group } };
        user.UserGroups = userGroups;
        group.UserGroups = userGroups;

        var users = new List<User> { user };

        var usersDto = users.Select(u =>
        {
            var dto = mapper.Map<User, UserDto>(u);
            dto.UserGroups = mapper.Map<IEnumerable<UserGroup>, IEnumerable<UserGroupDto>>(u.UserGroups).ToList();

            return dto;
        });
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM