This is part 1 in a blog series about yet another method for configuring your NHibernate mappings in code and writing conventions. Although there are mature solutions for doing this like Fluent NHibernate, I have found that they have required me to learn a new API and set of conventions, and sometimes the extension points I need haven't yet been implemented. I, like a lot of people, am most familiar with configuring NHibernate using xml files, so having a code based API that is very close in structure to an hbm document means I spend less time learning a new API, and more time getting my mappings written and out of the way. In this series, I will show you this API, and show you how simple it is to write your own custom mapping conventions on top of it.
Given the formula domain assemblies + automapping framework = nhibernate mapping.xml it is obvious we will need to somehow manipulate and produce an nhibernate mapping xml file in a structured way, using c# code. The way I do this is to use the LINQ To Xsd project to generate a statically typed representation of an NHibernate mapping file. Here is a simple mapping file, with the classic xml mapping on the left (thanks fincher.org), and Linq To Xsd based mapping on the right:
You can see how similar the xml and the code are. This allows you to use easily migrate from xml mapping to code mappings. We can get rid of magic strings and make the mapping refactor proof very easily, e.g. by replacing "NHibernatePets.Pet, NHibernatePets" with typeof(Pet).AssemblyQualifiedName, and using static reflection to get the property names.
To try this out, download nhibernate-configuration.cs and nhibernate-mapping.cs (the LINQ to XSD generated files) and include them in your project (you'll also need the Xml.Schema.Linq.dll from Linq to XSD), then bootstrap your NHibernate configuration using this snippet:
public static Configuration GetConfiguration(string connectionString)
{
var cfg = new Configuration();
var mappingXDoc = new hibernatemapping()
{
//add your mappings here
};
cfg.SetProperty(NHibernate.Cfg.Environment.Dialect, "NHibernate.Dialect.MsSql2008Dialect");
cfg.SetProperty(NHibernate.Cfg.Environment.ConnectionDriver, "NHibernate.Driver.SqlClientDriver");
cfg.SetProperty(NHibernate.Cfg.Environment.ConnectionString, connectionString);
cfg.SetProperty(NHibernate.Cfg.Environment.ConnectionProvider, "NHibernate.Connection.DriverConnectionProvider");
cfg.SetProperty(NHibernate.Cfg.Environment.ProxyFactoryFactoryClass, typeof(ProxyFactoryFactory).AssemblyQualifiedName);
cfg.AddXml(mappingXDoc.ToString());
return cfg;
}
Now you should be able to get started with writing typed mappings. Next time we’ll get started on conventions.
__________________________________________________________________________________________________________
This article was originally published (more or less) on my blog at www.adverseconditionals.com