Reputation: 993
I am using reflection and dynamic expressions to auto-populate a class and all its properties with fake data using bogus, my code looks like:
static Faker<T> AutoInferRules<T>() where T : class, new(){
var faker = new Faker<T>();
foreach (var property in typeof(T).GetProperties())
{
if (property.Name == "Schema")
{
continue;
}
try
{
if (property.PropertyType.IsClass && property.PropertyType != typeof(string))
{
// Recursively infer rules for nested classes
var nestedFaker = typeof(Program)
.GetMethod("AutoInferRules", BindingFlags.NonPublic | BindingFlags.Static)
?.MakeGenericMethod(property.PropertyType)
.Invoke(null, null);
faker = faker.RuleFor(property.Name, _ => nestedFaker);
}
else if (property.PropertyType == typeof(Double))
{
faker = faker.RuleFor(property.Name, (f, _) => f.Random.Double());
}
else if (property.PropertyType == typeof(Nullable<Boolean>))
{
faker = faker.RuleFor(property.Name, (f, _) => f.Random.Bool());
}
else if (property.PropertyType.IsGenericType &&
typeof(IList<>).IsAssignableFrom(property.PropertyType.GetGenericTypeDefinition()))
{
// Handle the case where the property is a List of objects
var elementType = property.PropertyType.GetGenericArguments()[0];
//gets defintion for GenerateList<T>
var generateListMethod = typeof(Program)
.GetMethods(BindingFlags.NonPublic | BindingFlags.Static).Last()
?.MakeGenericMethod(elementType);
var listExpression = Expression.Lambda<Func<T, List<T>>>(
Expression.Call(
generateListMethod,
Expression.New(generateListMethod!.ReturnType)
),
Expression.Parameter(typeof(T), "x")
);
faker = faker.RuleFor(property.Name,_ => listExpression);
}
else
{
// Generate rules for non-nested properties
faker = faker.RuleFor(property.Name, (f, _) => f.Random.AlphaNumeric(10));
}
}
catch (Exception ex)
{
Log.Logger.Error(ex, "error processing field {PropertyName}", property.Name);
}
}
return faker;
} static List GenerateList() where T : class, new() { // Here you can customize the logic to generate and populate the list var faker = AutoInferRules(); return new List { faker.Generate() }; }
When I run this code I get the following error:
Incorrect number of arguments supplied for call to method 'System.Collections.Generic.List`1[RandomFlightDataGen.Model.IATA_AIDX_FlightLegNotifRQ.FlightLegType] <$>g__GenerateList|0_2FlightLegType' (Parameter 'method')
The property it is failing on is a List<FlightLegType>
My Expression.Lambda looks like it matches the signature of the method I am trying to dynamically call
static List<T> GenerateList<T>() where T : class, new()
Anyone any ideas?
Upvotes: 0
Views: 64
Reputation: 71233
Not sure why you are passing an instance to a static function, or what the Expression.New
was supposed to do.
Looks like you just need:
var listExpression = Expression.Lambda<Func<T, List<T>>>(
Expression.Call(null, generateListMethod),
Expression.Parameter(typeof(T), "x")
);
Upvotes: -1