I'm trying to create an AutoFixture.ICustomization that loops over every type that inherits from my model base and then explicitly doesn't assign any values to properties that also derive from that model base.
Obviously, this requires some serious abuse of reflection.
So far, I've got this:
public class DiscosModelFixtureCustomizationNoLinks: ICustomization
{
public void Customize(IFixture fixture)
{
Type[] discosModelTypes = typeof(DiscosModelBase).Assembly.GetTypes().Where(t => t.IsDiscosModel() && !t.IsAbstract).ToArray();
MethodInfo customizeMethod = fixture.GetType().GetMethods().Single(m => m.Name == nameof(fixture.Customize) && m.IsGenericMethod); // Needed to resolve overload with generic
foreach (Type t in discosModelTypes)
{
MethodInfo constructedCustomizeMethod = customizeMethod.MakeGenericMethod(t);
Type customizationComposer = typeof(ICustomizationComposer<>).MakeGenericType(t);
PropertyInfo[] propsToIgnore = t.GetProperties().Where(p => p.PropertyType.IsDiscosModel()).ToArray();
foreach (PropertyInfo prop in propsToIgnore)
{
// I want to essentially do this
// For every prop that derives from DiscosModelBase
// fixture.Customize<DiscosObject>(c => c.Without(p => p.Id));
// Using my constructed method
constructedCustomizeMethod.Invoke(fixture, new [] {myExpression});
}
}
}
}
So .Customize<T>() has this signature:
void Customize<T>(Func<ICustomizationComposer<T>, ISpecimenBuilder> composerTransformation);
And ICustomizationComposer<T>.Without() has this signature:
IPostprocessComposer<T> Without<TProperty>(Expression<Func<T, TProperty>> propertyPicker);
So essentially, I need to work out how to build the equivalent of c => c.Without(p => p.Id) using reflection and my PropertyInfo.
This answer would indicated that I can manually build the expression tree, however, it's not really explained in enough detail that I'm able to apply it in this context.
First up, is this possible? Secondly, if so, how do I accomplish this missing step?