Generate builder

The following template generates a builder-like pattern when partial class is annotated with the [GenerateBuilder] attribute.

It then scans the class for all private fields which are not readonly and generates a WithX(Type var) and Without() that can be used to chain in a builder-like fashion:

Template

::foreach var classRef in class
  where classRef is partial and classRef has_attribute "GenerateBuilder";
::filename classRef;
using System;

namespace ::classRef.Namespace::;

partial class ::classRef::
{

    ::foreach var field in classRef.Fields
            where not field is readonly and field is private;
    public ::classRef:: With::field to pascalcase::(::field.Type:: ::field to camelcase to escape_keywords::)
    {
        ::field:: = ::field to camelcase to escape_keywords::;
        return this;
    }

    public ::classRef:: Without::field to pascalcase::()
    {
        ::field:: = default(::field.Type::);
        return this;
    }
    ::end;
}
::end;

Example class

namespace MyBuilders;

[GenerateBuilder]
public partial class PersonBuilder 
{
    private string _firstName;
    private string _lastName;
}

Generated output

namespace MyBuilders;

partial class PersonBuilder
{
    public PersonBuilder WithFirstName(string firstName)
    {
        _firstName = firstName;
        return this;
    }

    public PersonBuilder WithoutFirstName()
    {
        _firstName = default(string);
        return this;
    }

    public PersonBuilder WithLastName(string lastName)
    {
        _lastName = lastName;
        return this;
    }

    public PersonBuilder WihtoutLastName()
    {
        _lastName = default(string);
        return this;
    }
}