I'm writing a fluent api for constructing business data concepts to setup integration and regression tests.
I have the following:
public AndWithContext<T> AndWith(Action<T> withAction)
{
withAction(_instance);
return new AndWithContext<T>(_instance);
}
public AndWithContext<TOut> AndWith<TOut>(Func<T, TOut> withContextChangeFunc)
{
var output = withFunc(_instance);
return new AndWithContext<TOut>(output);
}
and an example of how I imagine one would want to use the Action<T>
portion of the api:
workOrder = c.Given<WorkOrder>()
.With(wo => wo.ReferenceNbr = 1234)
.AndWith(wo => wo.SpecOrder = specOrder)
.AndWith(wo => wo.WorkItems = workItems)
.Create();
I'm expecting the call to .AndWith(wo => wo.SpecOrder = specOrder)
to dispatch to the AndWith(Action<T>)
but it's landing on AndWith<TOut>(Func<T, TOut>)
Yes, I know I can make it work as desired by telling users to write with the following convention when assigning property values inside the context:
workOrder = c.Given<WorkOrder>()
.With(wo => wo.ReferenceNbr = 1234)
.AndWith(wo => {
wo.SpecOrder = specOrder;
wo.WorkItems = workItems;
return wo;
})
.Create();
But that's not the point.
Also interesting to me was that (wo => {wo.SpecOrder = specOrder;})
routes to the correct overload, but removing the braces and semicolon suddenly makes this behave like Func<T, TOut>
.
I'm sure this is happening for my WithContext
signatures too, but calls to my with context are all context shifting calls and are purely for readability and the beginning of the statement, so I kinda don't care about those.