4

I am trying to create an Object Builder so I can easily create objects for unit testing. I would like to create a With() method so I can pass in a Func<> and it will set the correct property for me.

Here is what I have so far:

public class EquipmentModelBuilder
{

    public EquipmentModel Object { get; set; }

    public EquipmentModelBuilder()
    {
        Object = new EquipmentModel();
    }

    public EquipmentModelBuilder WithCategory(int categoryId)
    {
        Object.EquipmentCategoryID = categoryId;
        return this;
    }

    public EquipmentModelBuilder With(Func<EquipmentModel> setter)
    {
        Object = setter.Invoke();
        return this;
    }

    public EquipmentModel Build()
    {
        return Object;
    }
}

Of course, the WithCategory() works, but I don't want to create all the methods for each property, I would like to be able to:

EquipmentModelBuilder.With(x => x.Property1 = 1).With(x => x.Property2 = "2").Build()

Any idea what I am doing wrong?

Martin
  • 11,031
  • 8
  • 50
  • 77

2 Answers2

3

You need to use an Action<EquipmentModel> as your argument rather than a Func<EquipmentModel>.

public EquipmentModelBuilder With(Action<EquipmentModel> setter)
{
    setter.Invoke(this.Object);
    return this;
}
StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315
  • 1
    +1 The call to `.Invoke` can be dropped, leaving a nicer `setter(this.Object)`. Then rename `setter` to `initializeProperties(this.Object)` :-) – Adam Houldsworth Mar 17 '11 at 15:29
  • @Adam: Good point. I personally prefer to do it the way you describe, while some people like to use "Invoke." I think it makes them feel more object-oriented. – StriplingWarrior Mar 17 '11 at 15:36
1

I think that Func<EquipmentModel> is specifying a function that returns an EquipmentModel, so what you would want is an Action<EquipmentModel> which specifies a function with no return that accepts an EquipmentModel as parameter.

Roly
  • 1,516
  • 1
  • 15
  • 26