Over the last little while there have been a raft of posts about using T4 templates, I think most of this seemed to be sparked from the drive to extend and gain more control over the Linq-to-Sql classes. So while there are a few good T4 templates to convert DBML files into classes there have been a number of drawbacks, some of these are pointed out here. The fact that L2S doesn’t support many-to-many relationships and the designer doesn’t let you specify the column lengths make using it for NHibernate (NH) related purposes fall a little short.
NHibernate XML Intellisense
On the next point, I know there has been a fair amount of hype around the Fluent NHibernate Mapping scene as well. I have never really found a few XML mapping files that hard to deal with. Here’s why:
Yep, once you’ve added the xsd definitions into Visual Studio’s schemas folder there’s intellisense and validation over any NH config.
T4 for Hbm.xml
If you’re creating a new project there is always the hassle of ensuring that your NH mappings have the same properties as your classes and all the methods and properties are virtual etc. So instead of converting a DBML file to NH mappings and classes, as mentioned before it is not really intended for this purpose. Here’s a small T4 template that you can use to convert .hbm.xml files into partial classes. So now, all you need to do is maintain an xml mapping file and let your class properties be automatically synchronised. My sample solution looks like this:
Inside the “BusinessObjectsGenerator.tt” is a simple generator that includes the desired business object structure and then specifies which xml files in the solution to generate partial classes for. The classes are partial so you can extend them with custom changes if needed in another file.
<#@ template language="C#v3.5" debug="True" hostspecific="True" #> <#@ include file="..\..\T4Templates\BusinessObjectsStructureTemplate.tt" #> <#@ output extension="log" #> <# BusinessObjectStructureTemplate template = new BusinessObjectStructureTemplate(); var pathBase = new System.IO.FileInfo(Host.TemplateFile).DirectoryName; BusinessObjectStructureTemplate.RenderClassFromHbm(pathBase, @"Mapping\Product.hbm.xml", template); BusinessObjectStructureTemplate.RenderClassFromHbm(pathBase, @"Mapping\Order.hbm.xml", template); BusinessObjectStructureTemplate.RenderClassFromHbm(pathBase, @"Mapping\Customer.hbm.xml", template); #>
If you’ve previously downloaded and looked into Damien’s L2S templates they look fairly complex. The easiest way I’ve found to produce T4 is with the T4 toolbox, and also using the T4 Editor by Tangible Engineering. However, currently if you’ve download the T4Toolbox, I had to download and compile rev#34560 which corrects an error when having T4 templates in a project that is nested in a solution folder.
On the inside
Most of the work is done inside the “BusinessObjectsStructureTemplate.tt” file. What I’ve done to try and keep things simple is use NH’s own ‘MappingDocumentParser’ class to parse the Xml file, then simply iterate through the config to populate some custom data structures that are applied to the template. The reason for this is the custom data classes inside the T4 templates can be extended and changed later if more flexibility is needed, also meaning a new adapter could be written instead of the NH version.
Choose one of these:
- System.BusinessObjects version: BusinessObjectsStructureTemplate.tt
- Generic POCO version: BusinessObjectsStructurePOCOTemplate.tt
And then include that file into the generator: