Create NHibernate classes using T4

Overview

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:

image

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:

image

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.

Sourcecode

Visit the T4 repository

Choose one of these:

  • System.BusinessObjects version: BusinessObjectsStructureTemplate.tt
  • Generic POCO version: BusinessObjectsStructurePOCOTemplate.tt

And then include that file into the generator:

  • BusinessObjectsGenerator.tt

Links

Create NHibernate classes using T4

.NET ASP.NET NHibernate
Posted by: Brendan Kowitz
Last revised: 21 Sep 2013 12:15PM

Comments

9/17/2009 9:53:27 AM
When i use your t4 code i got always following error:

Error 3 Compiling transformation: Type of conditional expression cannot be determined because there is no implicit conversion between 'NHibernate.Cfg.MappingSchema.HbmType' and 'string' c:\Daten\Work\VisualStudio2008\NHibernateGenerator\DataLayer\Mapping\BusinessObjectsStructureTemplate.tt 136 82 DataLayer


Whats Wrong?
9/17/2009 10:36:52 AM
Hi Viktor,

These templates can convert common properties/options into C# classes. Most other situations are easy to change and extend. Without seeing the mapping file I can't tell you the exact problem, but I can tell you there is a method inside BusinessObjectStructureTemplate.tt called "RenderClassFromHbm" which is having problems trying to convert the ID/Primary Key field. See code.google.com/.../Product.hbm.xml for my example. Please get back to me and we can extend the template to handle your config.

Brendan
9/19/2009 10:33:25 AM
Hi Brendan,
thank you for you reply.
i have downloaded your hole solutions and when i save the product.hbm.xml i get the following error:

Error 1 Compiling transformation: Type of conditional expression cannot be determined because there is no implicit conversion between 'NHibernate.Cfg.MappingSchema.HbmType' and 'string' c:\Daten\Work\VisualStudio2008\T4BusinessObjects\T4Templates\BusinessObjectsStructureTemplate.tt 136 82

Error 2 Compiling transformation: 'NHibernate.Cfg.MappingSchema.HbmSet' does not contain a definition for 'Item1' and no extension method 'Item1' accepting a first argument of type 'NHibernate.Cfg.MappingSchema.HbmSet' could be found (are you missing a using directive or an assembly reference?) c:\Daten\Work\VisualStudio2008\T4BusinessObjects\T4Templates\BusinessObjectsStructureTemplate.tt 168 75

Could you help me ?
Thanks
Viktor
12/18/2009 7:17:39 PM
This is great. T4 templates really help alleviate a lot of the issues that NHibernate causes because of its lack of tools at the moment. I'm not trying to be "spammy" but rather than rewrite it, I wanted to share a post with you guys that I wrote which is essentially a similar concept that Brendan blogged about but focuses on using T4 templates to reduce hard coded strings in ICriteria queries.

If you want to learn more about that, here is the article. sharpramblings.blogspot.com/.../...-api-usage.html
4/22/2010 8:15:18 AM
meilleures pages de casino virtuel
I would recommend using T4. I use it myself to generate code from UML-models. I create the models in UML, and then use T4 to generate classes from the models. I wrote a short blog post about it, check it out if you want some more info on my setup.If you have yet to try T4, there is no better place to start than Scott Hanselman's excellent post about that you can find here. Make sure you check the link list at the end of the post, it contains some of the best references for T4 information available.
4/22/2010 8:18:02 AM
meilleures pages de casino virtuel
I would recommend using T4. I use it myself to generate code from UML-models. I create the models in UML, and then use T4 to generate classes from the models. I wrote a short blog post about it, check it out if you want some more info on my setup.If you have yet to try T4, there is no better place to start than Scott Hanselman's excellent post about that you can find here. Make sure you check the link list at the end of the post, it contains some of the best references for T4 information available.....

No new comments are allowed on this post.