4

Fluent APIs are very common these days. Lately, I'm finding them in almost every system I work with. Mostly, they enhance readability but sometimes they lock me in to inflexible specifications, making understanding the runtime behavior of the specification that they build almost impossible. Is there a consensus on how to create a good fluent API? What are the best ways to represent a structure or specification using a fluent API?

I recently noticed this novel variant on the fluent API in the NServiceBus configuration class:

class EndpointConfig : IConfigureThisEndpoint, AsA_Server { }

It uses multiple interfaces as a kind of linear fluent interface. I like it because it doesn't place a heavy burden of extra code and context on me when I'm only trying to represent simple requirements. In simple cases that is adequate. I don't imagine it would scale to complex specifications, though. What do you think of this use of interfaces?

What other new idioms are you using in C#? Where do you use them? What are their strengths? Where wouldn't you use them? Also, how would you gauge the strengths of an idiom you were thinking of using?

Andrew Matthews
  • 3,006
  • 2
  • 29
  • 42

1 Answers1

1

I used to eschew boolean parameters on methods that indicated different behavior, e.g. I would take

int ExpensiveComputation(bool useDiskCache)

and prefer to turn it into

int ExpensiveComputation(CacheType.DiskCache)

I mostly preferred this because when you're calling ExpensiveComputation(true), it's not clear what the true means without knowing all about ExpensiveComputation, whereas ExpensiveComputation(CacheType.DiskCache) gives you a good idea.

However, with named parameters, I find it often acceptable to use the first, and call it like this: ExpensiveComputation(useDiskCache: true) So that's a recent idiom I've invented for myself.

mqp
  • 70,359
  • 14
  • 95
  • 123
  • Nice. I guess the fluent approach (which I hasten to add is worse than what you're proposing) to this would use your old way of doing things but naming the parameters to provide fluency: ExpensiveCalculation(using: DiskCache); I wonder whether this is in use anywhere? – Andrew Matthews Aug 18 '10 at 05:07