I have the following classes,
User:
public class User:Domain
{
[Sortable]
public string FirstName { get; set; }
[Sortable]
public string LastName { get; set; }
[NestedSortable]
public Profile Profile { get; set; }
}
Profile:
public class Profile : Domain
{
[Sortable]
public string BrandName { get; set; }
[NestedSortable]
public Client Client { get; set; }
[NestedSortable]
public ProfileContact ProfileContact { get; set; }
}
Client:
public class Client : Domain
{
[Sortable]
public string Name { get; set; }
}
Profile Contact:
public class ProfileContact : Domain
{
[Sortable]
public string Email { get; set; }
}
I'm writing a recursive function to get all the properties decorated with [Sortable]
attribute. This works well when I have a single [NestedSortableProperty]
but fails when I have more than one.
Here is my recursive function:
private static IEnumerable<SortTerm> GetTermsFromModel(
Type parentSortClass,
List<SortTerm> sortTerms,
string parentsName = null,
bool hasNavigation = false)
{
if (sortTerms is null)
{
sortTerms = new List<SortTerm>();
}
sortTerms.AddRange(parentSortClass.GetTypeInfo()
.DeclaredProperties
.Where(p => p.GetCustomAttributes<SortableAttribute>().Any())
.Select(p => new SortTerm
{
ParentName = parentSortClass.Name,
Name = hasNavigation ? $"{parentsName}.{p.Name}" : p.Name,
EntityName = p.GetCustomAttribute<SortableAttribute>().EntityProperty,
Default = p.GetCustomAttribute<SortableAttribute>().Default,
HasNavigation = hasNavigation
}));
var complexSortProperties = parentSortClass.GetTypeInfo()
.DeclaredProperties
.Where(p => p.GetCustomAttributes<NestedSortableAttribute>().Any());
if (complexSortProperties.Any())
{
foreach (var parentProperty in complexSortProperties)
{
var parentType = parentProperty.PropertyType;
if (string.IsNullOrWhiteSpace(parentsName))
{
parentsName = parentType.Name;
}
else
{
parentsName += $".{parentType.Name}";
}
return GetTermsFromModel(parentType, sortTerms, parentsName, true);
}
}
return sortTerms;
}
this happens because of the return statement inside the foreach
loop. How to rewrite this? with this example I need to get a list of FirstName
,LastName
,BrandName
,Name
and Email
. But I'm getting only the first four properties except Email
.
Now that the above issue is resolved by removing the return statement as posted in my own answer below and also following @Dialecticus comments to use yield return
. so I strike and updated the question.
Now I'm running into another issue. The parent class name is wrongly assigned if a class has multiple [NestedSortable]
properties.
This method is called first time with User
class like var declaredTerms = GetTermsFromModel(typeof(User), null);
Example,
After the first call, the parentsName
parameter will be null and [Sortable]
properties in User
class don't have any effect.
Now for the [NestedSortable]
Profile
property in User
class, the parentsName
will be Profile
and so the [Sortable]
properties in Profile
class will have Name
as Profile.BrandName
and so on.
Name
property in final list to be as follows,
Expected Output:
FirstName, LastName, Profile.BrandName, Profile.Client.Name, Profile.ProfileContact.Email
But Actual Output:
FirstName, LastName, Profile.BrandName, Profile.Client.Name, Profile.Client.ProfileContact.Email
Please assist on how to fix this.
Thanks,
Abdul