Alex Rivera | Logout

Conditional Builder Method Chaining Fluent Interface

Asked 2012-04-06T17:00:06.660
59

I was wondering what would be the best way to implement a .When condition in a fluent interface using method chaining in a Builder object?

For instance how would I implement the .WithSkill() and .When() methods in the following example:

var level = 5;

var ninja = NinjaBuilder
    .CreateNinja()
    .Named("Ninja Boy")
    .AtLevel(level)
    .WithShurikens(10)
    .WithSkill(Skill.HideInShadows)
        .When(level > 3)
    .Build()

Update - A sample solution can be found here.

Edit
Report

1 Answer

7

You could have a conditional optional parameter in your method that is true by default:

.WithSkill(Skill.HideInShadows, when: level > 3)

This will of course be very specific to the WithSkill method:

public NinjaBuilder WithSkill(Skill skill, bool when = true) {
  if (!when) return this;
  // ...
}

You could add it to other methods that you want to be conditional too.

Another option is to have a method that nests the conditional parts of the builder:

public NinjaBuilder When(bool condition, Action<NinjaBuilder> then) {
  if (condition) then(this);
  return this;
}

Then you can write it like this:

.When(level > 3, 
  then: _ => _.WithSkill(Skill.HideInShadows))

Or like this:

.When(level > 3, _=>_
  .WithSkill(Skill.HideInShadows)
)

This is more generic and can be used with any methods of the builder.

You can even add an optional "else":

public NinjaBuilder When(bool condition, Action<NinjaBuilder> then, Action<NinjaBuilder> otherwise = null) {
  if (condition) {
    then(this);
  }
  else if (otherwise != null) {
    otherwise(this);
  }
  return this;
}

Or, as a "mixin":

public interface MBuilder {}
public static class BuilderExtensions {
  public static TBuilder When<TBuilder>(this TBuilder self, bool condition, Action<TBuilder> then, Action<TBuilder> otherwise = null)
  where TBuilder : MBuilder
  {
    if (condition) {
      then(self);
    }
    else if (otherwise != null) {
      otherwise(self);
    }
    return self;
  }
}

public class NinjaBuilder : MBuilder ...

This is of course a way to create "if" statements as method calls. Other

answered 2012-04-06T17:02:27.720

Your Answer