Reputation: 45931
I'm developing an ASP.NET Web Api 2 service with .NET Framework 4.5.1 and C#.
I'm following this book to do it: ASP.NET MVC 4 and the Web API Building a REST Service from Start to Finish
I have these two classes.
User:
public class User
{
public int UserId { get; set; }
public string UserName { get; set; }
public virtual ICollection<Group> Groups { get; set; }
}
Group:
public class Group
{
public int GroupId { get; set; }
public string GroupName { get; set; }
public ICollection<User> Members { get; set; }
}
An User
could have Group
s, and a Group
has User
s as Members
.
These two classes are my Data.Models
and I use a Mapper
class to 'translate' them as Api.Models
with these two methods:
public Models.User CreateUser(Data.Models.User modelUser)
{
if (modelUser == null)
return null;
Models.User user = new Models.User()
{
UserId = modelUser.UserId,
UserName = modelUser.UserName
};
if (modelUser.Groups != null)
user.Groups = modelUser.Groups
.Select(CreateGroup)
.ToList();
}
public Models.Group CreateGroup(Data.Models.Group modelGroup)
{
if (modelGroup == null)
return null;
Models.Group group = new Models.Group
{
GroupId = modelGroup.GroupId,
GroupName = modelGroup.GroupName
};
if (modelGroup.Members != null)
group.Members = modelGroup.Members
.Select(CreateUser)
.ToList();
return group;
}
As you can see in Mapper
class, CreateUser
method calls CreateGroup
method, and CreateGroup
method calls CreateUser
.
In my case user1
is member of group1
and group1
has user1
as a member. So, I get this:
CreateUser
foruser1
it will call CreateGroup
for group1
.CreateGroup
for group1
it will call CreateUser
for user1
.Any idea about how to avoid this infinite recursive calls?
A solution could be to remove navigation properties like Groups
on User
, or Members
in Group
class from CreateUser
and CreateGroup
methods.
Upvotes: 0
Views: 148
Reputation: 48279
There are at least two possible solutions (I can think of two but there can be more).
(simple graph) split both your mapper methods into two - first one to initialize simple properties (name, id) and the second one to initialize navigation properties. Then, in a place in your code where you call the mapper, write a little bit longer script that makes use of these new methods that initialize navigation properties from user to groups but do not call the other method (from groups to users) so that you will have a graph of users poiting to groups.
(full graph) add a tail parameter to each of your methods that represents a list of objects that have already been visited. Then, upon recursive call, check if the element is already in the list and only if it is not - add it and call recursively. This way, recursive calls will explore whole dependency graph between users and groups and will make sure no user and no group is processed more than once.
Upvotes: 2