tags:

views:

56

answers:

3

Hi,

I'm using Visual Studio 2010, and have the tangibleT4EditorPlusModellingTools installed.

I'm just playing around with T4, having never touched it previously. What I'd like to do is look at one of my classes in the project, and write out each of the properties.

Could anyone give me absolute beginner tips to how the .tt file should be structured? I've googled this and haven't found an answer, so any help would be appreciated.

Thanks.

+1  A: 

Use Reflection in the tags.

Something like:

<#foreach (PropertyInfo info in myObject.GetType().GetProperties()){#>
    // do what you want with or any other property of info <#=info.Name#>
<#}#>

try the tuturials here msdn

<#@ template debug="false" language="C#" #>
<#@ output extension=".txt" #>
<#@ assembly name="System.Xml"#>
<#@ import namespace="System.Xml" #>
<#@ import namespace="System.Reflection" #>

<#
XmlDocument doc = new XmlDocument();
foreach (PropertyInfo info in doc.GetType().GetProperties()){#>
    <#=info.Name#>
<#}#> 

will print all properties of xmldocument

tsinik
That's probably the correct answer. Can you be a little more specific (perhaps with a code sample or a link) so that I can upvote you?
Robert Harvey
Thanks tsinik.I'd also up-vote with a more detailed explanation.
Paul
here is simple code example
tsinik
And how is myObject referencing the class?
Paul
you can create an instance by yourself.look at my answer i've added some code
tsinik
You cannot use reflection with t4 templates.
jfar
jfar, copy my code inside tt file in VS and see the results... it works
tsinik
Works like a charm!
marc_s
A: 

This is really hard as T4 templates and reflection don't play nice together.

See my answer to a similar, possible duplicate, question here:

Generate columnheaders based on the DisplayName attribute?

Update:

I don't need to check my answer, I have gone down this path and found reflection + t4 templates to be problematic. The banal example provided by the other answerer doesn't reflect the true complexity of the task the questioner is trying to accomplish. Try using a more realistic reflection target, like custom code, rather than a .NET class.

The reason why is clearly explained in the links I provided but since its easier to vote me down before reading links I'll post this here:

"An obvious first choice for accessing .NET metadata is Reflection. Built into .NET base class library, this API provides access to metadata of .NET types. Unfortunately, Reflection is optimized for code execution. One particular limitation makes it ill-suited for code generation - an assembly loaded using Reflection can only be unloaded with its AppDomain. Because T4 templates are compiled into .NET assemblies and cached to improve performance of code generation, using Reflection to access the component assembly causes T4 to lock it. This prevents you from changing/recompiling the component until you close and reopen the solution. While you can certainly live with this annoyance, it would be nice to avoid it."

jfar
please check your answers before posting, you are complitly wrong
tsinik
Maybe my answer required more nuance. Reflection could work but it requires re-opening a solution file anytime you change anything. Therefore developing t4 with reflection code has so much friction its just not a technique you can use. Anybody reading this should try this with their own changing model/domain classes and not something static like the .net api.
jfar
I've had some similar experiences to what jfar is mentioning.
JamesEggers
jfar, you are right about the locking, but the original question was about a beginner playing with t4, so the locking problem is irelevant since it is a simple exersize just to learn t4
tsinik
Paul
@tsinik I tend to try and make my answers as practical and "real world" as possible. Recommending an approach that fails miserable with real scenarios isn't a responsible way to answer questions.
jfar
+2  A: 

If the assembly you are reflecting over is part of your project (as the original question-raiser mentioned) then you will experience the locking as mentioned.

There is an interim solution as part of Oleg Sych's T4Toolbox codeplex project (http://t4toolbox.codeplex.com/), which provides a new VolatileAssembly directive which copies the assembly before loading it.

We're currently working on fixing this in the core T4 engine as soon as practical.

However, if you want to work with the code in your project, you may not want to deal with the compiled assembly, but the source code on disk, in which case the CodeModel inside VS is another option (if you can live with templates only running inside VS at design time).

There is an example of this at http://www.olegsych.com/2008/07/t4-template-for-generating-sql-view-from-csharp-enumeration/

GarethJ