Last week I discovered a rather wonderful construct for objects with long constructors, e.g. immutable value types:

public class UserProfile
{
	public string City { get; protected set; }
	public string Country { get; protected set; }
	public Uri Url { get; protected set; }
	public string Email { get; protected set; }
	public string Tagline { get; protected set; }

	public UserProfile(string city, string country, Uri url, string email,
		string tagline)
	{
		...
	}
}

This constructor has bad Connascence of Position (CoP); to construct a UserProfile instance, users have to know the position of each parameter. Otherwise they might mix up the city with the country for example:

// Spot the bug!
var profile = new UserProfile("NZ", "Wellington",
	new Uri("http://richarddingwall.name"), "rdingwall@gmail.com", ".NET guy"); 

This won’t be a problem with named parameters in C# 4.0, but until then, a nice alternative is a fluent builder class as described here:

UserProfile profile = new UserProfileBuilder()
	.WithCity("Wellington")
	.WithCountry("NZ")
	.WithUrl(new Uri("http://richarddingwall.name"))
	.WithEmail("rdingwall@gmail.com")
	.WithTagline(".NET guy");

Builders are very easy to implement. Each With method records its value and returns the current builder instance. Then we provide an implicit cast operator that finally constructs a UserProfile with all the parameters in the right places.

public class UserProfileBuilder
{
	internal string City { get; set; }
	internal string Country { get; set; }
	// ... etc

	public UserProfileBuilder WithCity(string city)
	{
		this.City = city;
		return this;
	}

	// ... etc

	public static implicit operator UserProfile(UserProfileBuilder builder)
	{
		return new UserProfile(builder.City, builder.Country, builder.Url,
			builder.Email, builder.Tagline);
	}
}

I really like this!

June 1st, 2009 | 5 Comments
5 Responses to “Fluent Builder Pattern for classes with long-ish constructors” Leave your Comment
  1. John Varga says:

    Be aware that in your “With” example, the var will get confused and you will have a UserProfileBuilder instead of a UserProfile. You need to use an explicit type declaration.

  2. Richard says:

    @John whoops! Good spotting… fixed.

  3. John Varga says:

    I only know this because I saw someone else post this pattern and I thought it was amazingly badass so I happened to remember that pitfall.

  4. Ed Blackburn says:

    You could still use var, if you have a:

    public UserProfile Build() member.

    Your public static implicit operator UserProfile member could implement Build() to keep it nice and DRY?

  5. Richard says:

    @Ed: after a couple of weeks using this I’m inclined to agree. We’ve discovered the static operators aren’t much good for subclassed builders (e.g. AdminUserBuilder) because they cannot be inherited/overriden.