0

I am using T4 templates and the T4 Toolbox to generate text.

I would like to do partial updates based on regions. For instance, on the first pass everything would be generated, but if the file was updated again, only the code blocks in the $regions would be updated. Each of the $regions would have a distinct name.

I am looking for suggestions on how this could be implemented.

One way would be using a a custom pre-processor that strips out everything but the generated code regions. Another may be to flush out the T4 processor's buffer when a generated code region is found, then when the end of the region is found, replace the text in the generated file's region that corresponds to the one the T4 processor has parsed.

Assumptions

  • Generated code regions would not contain blocks that should be parsed
  • Each generated text region has a distinct name

Simplistic Example

<person>
    <firstname>
      $region FirstName generated
      <#="//T4 Template stuff here" #>
      $endregion
    </firstname>

    <lastname>
      $region LastName generated
      <#="//T4 Template stuff here" #>
      $endregion
    </lastname>

</person>

NOTE: I realize this question is similar to this question, but a suitable answer was never provided. I am looking for a viable solution instead of "it cant be done".

Community
  • 1
  • 1
Brian
  • 6,910
  • 8
  • 44
  • 82
  • 1
    The reason no answer was provided is because there's no good answer. In order to get what you are asking for I would probably not use T4 at all but instead write an external tool relying on roslyn to parse C# into a syntax tree and replace said regions. This is then applied on the Project. A good answer that requires refactoring is to rely on partial classes and methods. That is how C# is designed to mix generated code with hand written code. Then T4 works like a charm. – Just another metaprogrammer Oct 21 '12 at 11:15
  • Continuation of how to use partial: Using works kind of the opposite you are proposing. You use T4 to generate the scaffold and then use partial to inject behaviors – Just another metaprogrammer Oct 21 '12 at 11:16

2 Answers2

1

This is exactly what partial classes, methods, and MetadataType were created for.

In the linked question the guy claims partial classes aren't an option without explaining it, you have made no such stipulation. If those are not an option, give details on why.

Maslow
  • 18,464
  • 20
  • 106
  • 193
  • Either partial classes or partial methods. No good way to do it unless you parse the file because regions are not available in reflection or introspection. – Dustin Davis Mar 15 '13 at 22:55
  • sure, not updating code within regions, but I see nothing here that would prevent the actual intended assembly output from being achieved with these capabilities. – Maslow Mar 16 '13 at 01:03
0

You have the option of typing the non-changing text into a .cs file or another .tt file and having a T4 import or otherwise use the code in the other file to create a file with both items merged.

The .cs file that isn't going to be actually compiled can be set to None for the build action instead of Compile.

Actually you could just read the raw text of the non-changing .cs file stopping on your special region lines to insert whatever the T4 deems appropriate on this run. For that matter, I don't see anything stopping you from having the T4 read the existing file it created, and only changing text inside the regions.

Simple text parsing of a .cs file can look for the #region lines.

Maslow
  • 18,464
  • 20
  • 106
  • 193