July 15th, 2010
Instead of writing
string query =
"select * " +
"from Customer " +
"where CustomerID = @customerID";
or
string xml =
"<Customers> " + Environment.NewLine +
" <Customer> " + Environment.NewLine +
" <ID value=\"12\"/> " + Environment.NewLine +
" </Customer> " + Environment.NewLine +
"</Customers>";
one can write
string query =
"select *
from Customer
where CustomerID = @customerID";
or
string xml =
@"
<Customers>
<Customer>
<ID value='12'/>
</Customer>
</Customers>
";
with just quotation marks in the beginning and end – not at every row.
Note how one can write apostrophes ( ‘ ) instead of quotation mark ( ” ) for the xml attributes.
The at sign ( @ ) is there to tell the parser that any back slashes ( \ ) should be treated like regular characters and not escape characters. Very useful when handling files and folders on the Windows platform. Not very useful in my example.
Also note that if you want an xml declaration <?xml version=’1.0′ encoding=’utf-8’ ?> it must be before any whitespace
string xml =
@"<?xml version='1.0' encoding='utf-8' ?>
<Customers>
...
In Vbnet one can write XML inline – like if it is a part of the language.
July 15th, 2010
When working with Microsoft’s Text Template Transformation Toolkit there is a lot of ctrl-tabbing to and fro to validate the result.
Instead split the editor (I am talking Visual studio here) vertically and put the .tt file in one and the output (.cs) file in the other. Whenever you save the .tt file the output file is updated. It even remembers the scrolling position.
July 15th, 2010
Update: use this tip instead.
One can call a template from another through <#@ include file=”MyTemplateTemplate.tt” #> Variables defined in MyTemplate.tt are then transfered to MyTemplateTemplate.tt. The trick is to set them in the right order.
Below is also shown a way to avoid unnecessary output. Here is [another].
MyTemplate.tt:
<#
string Greeting = "HelloWorld";
bool createOutput = true;
#>
<#@ include file="MyTemplateTemplate.tt" #>
MyTemplateTemplate.tt:
<#
if( !createOutput )
{
return "// This file is not in use.";
}
#>
…the template code
<#+
bool createOutput = false;
string Greeting = string.Empty;
#>
As you can see the TemplateTemplate has the variable assignment as a statement “<#+” below/after the code.
Then there is the createOutput flag as a trick to avoid output. Return blank if you want an empty file. Another way to avoid compilable code that won’t compile is here.
July 15th, 2010
Say you have a handy parameter driven T4 template to create a business object BusinessObject.tt. You then have one T4-file per business object Customer.tt, User.tt, Role.tt. Now when editing BusinessObject.tt it outputs a .cs file with a class name like MyClass. This output file will naturally not compile since MyClass isn’t part of your domain.
A simple solution is to set <#@ output extension=”.txt” #> in BusinessObject.tt but keep <#@ output extension=”.cs” #> in Customer.tt, User.tt etc.
A drawback is that the output from BusinessObject.tt won’t compile so you won’t get feedback from the compiler. My workaround for this is to save Customer.tt once in a while to check for compilation errors.
Here is another way.
July 15th, 2010
Download the templates from Tangible, there is a gratis version.
Use the Simple and the Advanced templates from Tangible.
Read Oleg’s article.
You might notice that T4 once in a while complains about a right parenthesis. This is often a false error. In some cases you get more errors so just skip to the right-parenthesis-complaint and they will vanish. Other cases this is the only error. Just type a character and delete it and save again. It can even be enough to just step away from the edited row.
The error is always on the same row as the cursor is positioned.
If you know that the output should compile but the compiler complains every time you save the .tt file it is working as it should. Saving the .tt file runs the template transformation but doesn’t start any compilation. So just compile after saving the .tt file and all should be well.
July 15th, 2010
If you are using T4 and get this error you are probably having an error in the template which makes it fail transforming. Check here for a tidbit more information.
An error example:
Error 11 A namespace cannot directly contain members such as fields or methods C:\MyProject\MyOutputFile.cs 1 1 MyProjectName
July 12th, 2010
Avoid
try{
...
}catch( Exception exc ){
...
throw exc;
}
since it destroys the exception stack.
Instead write
try{
...
}catch( Exception ){
...
throw;
}
If you don’t understand what “destroying the exception stack” means you probably don’t want to destroy it and this recommendation is even more something to heed.
To get to the exception use $exception.
July 12th, 2010
In dotnet one can write
try{
...
}catch(Exception){
throw;
}
which gives two debugging tools. The first is the ability to set a break point on the catch line.
Note how I haven’t written catch( Exception exc) but only catch( Exception). This makes us avoid a compiler warning because we don’t use the exc variable. Which brings us to trick number two in Visual studio: Since we don’t have a variable with the exception instead write $exception in the immediate window or the quickwatch window. $exception brings forward the [hidden] exception reference.
Also note how there is no variable behind the throw statement. This makes the framework hide the catch/throw and leave the stack intact.
Update: In VisualStudio2010 it looks like it is enough to write exception in the quickwatch window.
With dotnet 4.5.1? one can write $ReturnValue the same way to get to the… the… the… return value!
June 29th, 2010
If you want to do threading the nice dotnet4 way with myList.AsParallel().ForEach but are stuck in a 3.5 environment look here.
June 12th, 2010
Trying out AspnetMVC2 and MvcContrib you might run into
Could not load file or assembly ‘Microsoft.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null’ or one of its dependencies. The system cannot find the file specified.
The solution is to get the file Microsoft.Web.Mvc.dll from the downloaded zip. Drop the file into the bin folder of the site (add it somewhere else, like “MvcContrib” and set it to copy to the bin folder.
I presently have a post-build event command
copy $(SolutionDir)External\MvcContrib\Microsoft.Web.Mvc.dll $(TargetDir)
I also use dotnet4 which might have to do with the error message.