Fluently setting C# properties and chaining methods

Posted by John Feminella on Stack Overflow See other posts from Stack Overflow or by John Feminella
Published on 2010-03-13T15:40:05Z Indexed on 2010/03/13 15:45 UTC
Read the original article Hit count: 293

Filed under:
|
|
|

I'm using .NET 3.5. We have some complex third-party classes which are automatically generated and out of my control, but which we must work with for testing purposes. I see my team doing a lot of deeply-nested property getting/setting in our test code, and it's getting pretty cumbersome.

To remedy the problem, I'd like to make a fluent interface for setting properties on the various objects in the hierarchical tree. There are a large number of properties and classes in this third-party library, and it would be too tedious to map everything manually.

My initial thought was to just use object initializers. Red, Blue, and Green are properties, and Mix() is a method that sets a fourth property Color to the closest RGB-safe color with that mixed color. Paints must be homogenized with Stir() before they can be used.

Bucket b = new Bucket() {
  Paint = new Paint() {
    Red = 0.4;
    Blue = 0.2;
    Green = 0.1;
  }
};

That works to initialize the Paint, but I need to chain Mix() and other methods to it. Next attempt:

Create<Bucket>(Create<Paint>()
  .SetRed(0.4)
  .SetBlue(0.2)
  .SetGreen(0.1)
  .Mix().Stir()
)

But that doesn't scale well, because I'd have to define a method for each property I want to set, and there are hundreds of different properties in all the classes. Also, C# doesn't have a way to dynamically define methods prior to C# 4, so I don't think I can hook into things to do this automatically in some way.

Third attempt:

Create<Bucket>(Create<Paint>().Set(p => {
    p.Red = 0.4;
    p.Blue = 0.2;
    p.Green = 0.1;
  }).Mix().Stir()
)

That doesn't look too bad, and seems like it'd be feasible. Is this an advisable approach? Is it possible to write a Set method that works this way? Or should I be pursuing an alternate strategy?

© Stack Overflow or respective owner

Related posts about fluent-interface

Related posts about c#