AArnott/ImmutableObjectGraph — pull request #25 by ProductiveRage (2014-09-29 22:09:22+00:00)
Title: Generate a NuGet package (and prevent the templates being copied into each consuming project)

Hi -

I've made some changes to try to organise things into a NuGet package. In doing so, I've made a couple of decisions that hopefully make things as easy as possible for someone to consume the package that hopefully aren't *too* controversial; I didn't include the templates in the package "content" folder so they're not copied straight into the target project. (I was hoping that this overlapped with the spirit of Issue #10 "The T4 template should not require source distribution"). I also removed the Immutable library reference from the main project, which required injecting the methods from the "CollectionExtensions" class into the generated types (if any of the fields are collection types). This does mean that there is duplication of code in the generated output but it means that none of the released templates have to reference the Immutable library, which they would have had to do with a hard-coded package location string. Now, if the consuming project has templates that utilise the immutable types then the templates there specify what version to use. For example,

<#@ template debug="true" language="C#" #>
<#@ Output Extension=".generated.cs" #>
<#@ assembly name="$(SolutionDir)packages\Microsoft.Bcl.Immutable.1.0.34\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll" #>
<#@ Import Namespace="System.Collections.Immutable" #>
<#
this.Namespace = "Demo";
#>
<#@ Include File="$(SolutionDir)packages\ImmutableObjectGraph.1.0.0\templates\ImmutableObjectGraph.tt" #>
<#+
class Message {
Contact author;
ImmutableList to;
ImmutableList cc;
ImmutableList bcc;
string subject;
string body;
}

class Contact {
string name;
string email;
}
#>

This could be tidied up so that the consuming project has a "base" template such as

<#@ assembly name="$(SolutionDir)packages\Microsoft.Bcl.Immutable.1.0.34\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll" #>
<#@ Import Namespace="System.Collections.Immutable" #>
<#@ Include File="$(SolutionDir)packages\ImmutableObjectGraph.1.0.0\templates\ImmutableObjectGraph.tt" #>

which the individual templates import with

<#@ template debug="true" language="C#" #>
<#@ Output Extension=".generated.cs" #>
<#
this.Namespace = "Demo";
#>
<#@ Include File="BaseImmutableObjectGraph.tt" #>
<#+
class Message {
Contact author;
ImmutableList to;
ImmutableList cc;
ImmutableList bcc;
string subject;
string body;
}

class Contact {
string name;
string email;
}
#>

That way, each project only has to have a single "text" reference to "ImmutableObjectGraph.tt" and to "System.Collections.Immutable.dll" (so that if either package is updated, there's only a single place that the version numbers must be changed).

I thought it would be really helpful to have this as a NuGet package (I know that I looked for one almost as soon as someone pointed me to your work) and I think the approach I've taken is the least invasive for someone pulling in the package.

You can generate a new .nupkg file by building the project in Release configuration and running "NuGetBuild\BuildNuGetPackage.bat".

I'd be interested in hearing your thoughts! I wasn't so presumptious as to publish it right now, but I am eagerly anticipating its availability assuming you're ok with these changes - and I'd be happy to publish it if you're happy for me to do so! :)