Skip to content

Instantly share code, notes, and snippets.

@JamesDunne
Created October 6, 2011 03:43
Show Gist options
  • Save JamesDunne/1266453 to your computer and use it in GitHub Desktop.
Save JamesDunne/1266453 to your computer and use it in GitHub Desktop.
A Visual Studio T4 template for generating immutable object models in C#
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core.dll" #>
<#@ import namespace="System.Linq" #>
<#@ output extension=".generated.cs" #><#
// Describe the immutable model types to generate:
var types = new[] {
new {
name = "ImmutableSample",
comment = "A complete commit object.",
idType = "int",
members = new[] {
new { name = "Items", type = "string[]", bType = "List<string>", convert = "({0}).ToArray()", revert = "({0}).ToList()" },
new { name = "ForeignKeyID", type = "int", bType = (string)null, convert = (string)null, revert = (string)null },
new { name = "ModifiedBy", type = "string", bType = (string)null, convert = (string)null, revert = (string)null },
new { name = "ModifiedDate", type = "DateTimeOffset", bType = (string)null, convert = (string)null, revert = (string)null },
new { name = "Message", type = "string", bType = (string)null, convert = (string)null, revert = (string)null },
}
},
};
#>
using System;
using System.Collections.Generic;
using System.Linq;
namespace ImmutableModels
{
<#
for (int i = 0; i < types.Length; ++i)
{
var ty = types[i];
if (i != 0)
{
#>
<#
} // if (i != 0)
if (ty.comment != (string)null)
{
#>
/// <summary>
/// <#= ty.comment #>
/// </summary>
<#
} // if (ty.comment != (string)null)
#>
public sealed partial class <#= ty.name #>
{
<#
if (ty.idType != (string)null)
{
#>
public <#= ty.idType #> ID { get; private set; }
<#
} // if (ty.idType != (string)null)
// Public read-only properties:
for (int j = 0; j < ty.members.Length; ++j)
{
var mbr = ty.members[j];
#>
public <#= mbr.type #> <#= mbr.name #> { get; private set; }
<#
} // for (int j = 0; j < ty.members.Length; ++j)
#>
public <#= ty.name #>(Builder b)
{
<#
// Property assignment statements:
for (int j = 0; j < ty.members.Length; ++j)
{
var mbr = ty.members[j];
#>
this.<#= mbr.name #> = <#= mbr.convert == null ? "b." + mbr.name : String.Format(mbr.convert, "b." + mbr.name, mbr.type, mbr.bType) #>;
<#
} // for (int j = 0; j < ty.members.Length; ++j)
#>
}
public sealed class Builder
{
<#
// Public read-write properties:
for (int j = 0; j < ty.members.Length; ++j)
{
var mbr = ty.members[j];
#>
public <#= mbr.bType ?? mbr.type #> <#= mbr.name #> { get; set; }
<#
} // for (int j = 0; j < ty.members.Length; ++j)
#>
public Builder() { }
public Builder(<#= ty.name #> imm)
{
<#
for (int j = 0; j < ty.members.Length; ++j)
{
var mbr = ty.members[j];
#>
this.<#= mbr.name #> = <#= mbr.revert == null ? "imm." + mbr.name : String.Format(mbr.revert, "imm." + mbr.name, mbr.type, mbr.bType) #>;
<#
} // for (int j = 0; j < ty.members.Length; ++j)
#>
}
public Builder(
<#
bool doComma = false;
for (int j = 0; j < ty.members.Length; ++j)
{
var mbr = ty.members[j];
#>
<#= doComma ? "," : " " #><#= mbr.bType ?? mbr.type #> p<#= mbr.name #>
<#
doComma = true;
} // for (int j = 0; j < ty.members.Length; ++j)
#>
)
{
<#
for (int j = 0; j < ty.members.Length; ++j)
{
var mbr = ty.members[j];
#>
this.<#= mbr.name #> = p<#= mbr.name #>;
<#
} // for (int j = 0; j < ty.members.Length; ++j)
#>
}
}
public static implicit operator <#= ty.name #>(Builder b)
{
return new <#= ty.name #>(b);
}
}
<#
} // for (int i = 0; i < types.Length; ++i)
#>
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment