We're working on a project that has a user consisting of roles, and the roles consist of more granular functions, and we're trying to map the many-to-many relationships of the DTOs to our Business Objects. Here's an example of the DTOs:
public class UserDto {
public Guid Id { get; set; }
public string Username { get; set; }
public virtual ICollection<UserRoleDto> UserRoles { get; set; }
}
public class UserRoleDto {
public virtual Guid UserId { get; set; }
public virtual UserDto User { get; set; }
public virtual Guid RoleId { get; set; }
public virtual RoleDto Role { get; set; }
}
public class RoleDto {
public Guid Id { get; set; }
public string Name { get; set; }
public virtual ICollection<RoleFunctionDto> RoleFunctions { get; set; }
public virtual ICollection<UserRoleDto> UserRoles { get; set; }
}
public class RoleFunctionDto{
public virtual Guid RoleId { get; set; }
public virtual RoleDto Role { get; set; }
public virtual Guid FunctionId { get; set; }
public virtual FunctionDto Function { get; set; }
}
public class FunctionDto {
public Guid Id { get; set; }
public string Name { get; set; }
public virtual ICollection<RoleFunctionDto> RoleFunctions { get; set; }
}
Ideally we want to abstract the joining DTO's away from the business layer. Something like:
public class User {
public Guid Id { get; set; }
public string Username { get; set; }
public ICollection<Role> Roles { get; set; }
// This would be nice to pull from the child roles... but not a must
public ICollection<Function> Functions { get; set; }
}
public class Role {
public Guid Id { get; set; }
public string Name { get; set; }
public ICollection<Function> Functions { get; set; }
}
public class Function {
public Guid Id { get; set; }
public String Name { get; set; }
}
I've read through the automapper documentation and I can't wrap my head around how to set these mappings up correctly.
I'd like to be able to map from UserDto to User (and back) and have the object graph populate.
So If I think I can get the Business Object mapping via:
Mapper.CreateMap<UserDto, User>()
.AfterMap((s, d) => {
// Create the mappings for the many-to-many like:
foreach(var roleDto in d.UserRoles)
{
// Do I call the Mapper.Map function here?
s.Roles.Add(Mapper.Map<Role>(roleDto));
}
// Then loop through the mapped functions in the roles to add them to Functions?
})
However, will this just cause a circular mapping when the RoleDto maps, and gets a hold of the UserRoles collection?
I've read that Automapper isn't really great at unflattening the object graph, so how can I go about reversing this process? Just do the same thing but in reverse, calling Mapper.Map?