How do I modify the pre-built templates?

Jan 6, 2010 at 3:12 AM

I've generated code using the Linq to SQL model, and now I would like to perform a few minor modifications to it (I'd like to add serialization tags to a few things, for example). Is there an article on how to do this? I didn't see one on the main page, but perhaps I'm missing something. I know I'm to modify a .tt file, but I'm not sure whether I modify my newly created .tt file, or the LinqToSqlGenerator. I'm also not sure how to make the modifications, but I think I'll be able to figure that part out of once I get started.

Thanks!

Jan 6, 2010 at 12:19 PM
Edited Jan 6, 2010 at 12:21 PM

The basic idea would be to not modify any of the classes that are part of the T4 toolbox but to derive your own from them and modify their behavior by overriding methods. It's probably better to not modify the T4 toolbox unless you find no other way around it (which is a problem I had that I describe here). In your case it would probably be best to:

  1. derive your own class from LinqToSqlEntityClassTemplate
  2. override the method 'public override string TransformText()', and copy the base classes implementation of that method into your overriding method (as a starting point)
  3. you will probably wan't to add you own method, something like 'RenderSerializationAttribute()' right after the call to 'RenderTableAttribute()'
  4. in your main tt file you will need to tell the generator to use your derived class instead of the one internal to the T4 toolbox:

 

<#
// <copyright file="MySchema.tt" company="Microsoft">
//  Copyright © Microsoft. All Rights Reserved.
// </copyright>
#>
<#@ template language="C#" hostspecific="True" debug="True" #>
<#@ xsd processor="T4Toolbox.XsdProcessor" file="%VS100COMNTOOLS%\..\..\Xml\Schemas\DbmlSchema.xsd" #>
<#@ output extension="log" #>
<#@ include file="T4Toolbox.tt" #>
<#@ include file="T4Toolbox\LinqToSql.tt" #>
<#@ include file="..\T4\LinqToSql.tt" #> // <-- This file contains MyCustomLinqToSqlEntityClasseTemplate 
<#
	// Generate entity classes from a LINQ to SQL class model (.dbml file)
	LinqToSqlGenerator generator = new LinqToSqlGenerator();
	generator.DbmlFile = "MySchema.dbml";
	
	generator.EntityClassTemplate = new MyCustomLinqToSqlEntityClassTemplate();

	generator.Run();
#>

 

 

Coordinator
Jan 6, 2010 at 1:11 PM

Yes, this is the intended way to modify the generated output.

@a5cent, could you elaborate on why this approach didn't work for you?

Oleg

Jan 6, 2010 at 4:16 PM

Thank you very much!

Jan 6, 2010 at 5:16 PM
Edited Jan 6, 2010 at 5:21 PM

Hi Oleg

All of the „real“, functional changes to the generated code I was able to handle with the recommended approach. Then I needed to make the generated code conform to our coding style guidelines which are enforced by ReSharper. For example, I was required to remove ‘this.’ from the generated code where it is not absolutely necessary. This impacted the following methods:

 

private void RenderConstructor()
private void RenderEntityRefProperty(Association association)
private void RenderEntitySetProperty(Association association)
private void RenderEntitySetActionMethods(Association association)
private void RenderProperty(Column column)
private void RenderPropertyChangeMethods()
private void RenderSerializationField()

Because these are non-virtual, and some of them { e.g. RenderEntityRefProperty() and RenderEntitySetProperty() } are called from within other private methods I needed to provide my own implementation for these too { e.g. RenderProperty() }.

 

The sum of the methods I now needed to provide myself (real functionality and style guidelines related stuff) weighed substantially more then what was left in the base class. It was thought that the dependency on a marginally used base class made the implementation harder to understand then providing a complete replacement for it. That is what I described here. However, it was incorrect to say that achieving my goal was impossible with the recommended approach.

Not having this ‘interface-feature’ isn’t something I consider a major problem and it won’t stop us from using the T4 Toolbox, because declaring the interfaces and getting the generator to use them is a small change we can do ourselves.

Another reason we had for a T4 Toolbox modification, although not directly related to this discussion, was prefixing private field members with an underscore (another one of our coding style rules). Again a rather small and simple change, but it would be nice if there was a way to configure the CSharpTemplate at a single location for all template classes that derive from it.

Jan 7, 2010 at 2:37 PM
pateras wrote:

I've generated code using the Linq to SQL model, and now I would like to perform a few minor modifications to it (I'd like to add serialization tags to a few things, for example). Is there an article on how to do this?... Thanks!

 
Pat --

(This may be slightly off-track; but, not altogether unrelated.)

FYI, I have a full working sample using T4 templates, T4 ToolBox, Linq To Sql, LinqToSqlEntityBase, Repository design pattern, and a few other goodies.

If you are interested, it is free and found here...

http://mkamoski1.wordpress.com/2009/12/01/t4-t4-toolbox-linq-to-sql-entity-base-code-description/

HTH.

Thank you.

-- Mark Kamoski