<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom">
  
  <title>Fluent NHibernate Blog</title>
  
  <link href="http://fluentnhibernate.org/blog" />
  <updated>2011-04-03T20:21:32+00:00</updated>
  <id>http://fluentnhibernate.org/blog</id>
  <author>
    <name>James Gregory</name>
    <email>james@jagregory.com</email>
  </author>


  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/fnh" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="fnh" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
    <title>Fluent NHibernate 1.2 released</title>
    <link href="http://fluentnhibernate.org/blog/blog/2011/04/03/fluent-nhibernate-1.2-released.html" />
    <updated>2011-04-03T00:00:00+00:00</updated>
    <id>http://fluentnhibernate.org/blog/blog/2011/04/03/fluent-nhibernate-1.2-released</id>
    <content type="html">&lt;p&gt;It&amp;#8217;s been a long time coming. Fluent NHibernate 1.2 is now officially released. You can download it from the &lt;a href='http://fluentnhibernate.org/downloads'&gt;website downloads page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The bulk of changes are bugfixes, but we&amp;#8217;ve also upgraded to NHibernate 3.1. There&amp;#8217;s a few fancy things around &lt;a href='http://wiki.fluentnhibernate.org/Fluent_mapping#Access_strategies'&gt;access strategies&lt;/a&gt; and &lt;a href='http://wiki.fluentnhibernate.org/Fluent_mapping#Collection_types'&gt;IEnumerable&amp;#8217;s&lt;/a&gt;, and some &lt;a href='https://github.com/jagregory/fluent-nhibernate/commit/8c7ad8d3887d7c5146a8982e06e9062986bf15e4'&gt;diagnostics&lt;/a&gt; thrown in for good measure. For everything else, you can read the &lt;a href='http://wiki.fluentnhibernate.org/Release_notes_1.2'&gt;release notes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We&amp;#8217;ve also taken ownership of the &lt;a href='http://nuget.org/List/Packages/FluentNHibernate'&gt;Fluent NHibernate Nuget package&lt;/a&gt; which has been updated for this release.&lt;/p&gt;

&lt;p&gt;This will hopefully be the last release of our 1.x code path, which will give us plenty of time to work on some shiny features for 2.0.&lt;/p&gt;</content>
  </entry>

  <entry>
    <title>Field support (1.1 Feature Focus)</title>
    <link href="http://fluentnhibernate.org/blog/blog/2010/05/23/feature-focus-fields.html" />
    <updated>2010-05-23T00:00:00+00:00</updated>
    <id>http://fluentnhibernate.org/blog/blog/2010/05/23/feature-focus-fields</id>
    <content type="html">&lt;p&gt;Fluent NHibernate has always had an hard-coded restriction on what members you can use for mapping. In some cases this restriction is fairly sensible (static reflection doesn&amp;#8217;t support exposing private fields), but in other cases it doesn&amp;#8217;t make much sense (automapping).&lt;/p&gt;

&lt;p&gt;With the advent of 1.1, we now have full private member support.&lt;/p&gt;

&lt;h2 id='classmaps'&gt;ClassMaps&lt;/h2&gt;

&lt;p&gt;The mapping interface is still limited by the capabilities of expression building, so you still can&amp;#8217;t use the traditional &lt;code&gt;Map(x =&gt; x.field)&lt;/code&gt; syntax to expose fields (private ones, anyway); however, the &lt;code&gt;Reveal&lt;/code&gt; functionality is now capable of exposing fields as well as private properties.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Reveal.Member&amp;lt;YourEntity&amp;gt;(&amp;quot;_privateField&amp;quot;);

Map(Reveal.Member&amp;lt;YourEntity&amp;gt;(&amp;quot;_privateField&amp;quot;));&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Any method that accepts an &lt;code&gt;Expression&lt;/code&gt; can now be used with the above syntax. It&amp;#8217;s not compile-safe, but some sacrifices have to be made.&lt;/p&gt;

&lt;h2 id='automapping'&gt;Automapping&lt;/h2&gt;

&lt;p&gt;The area where these changes really shine is automapping. The automapper is now fully capable of dealing with fields as a legitimate way to persist your entities.&lt;/p&gt;

&lt;p&gt;Using the automapping configuration style (highlighted in the &lt;a href='/blog/2010/05/23/feature-focus-automapping.html'&gt;automapping configuration feature focus&lt;/a&gt;) we&amp;#8217;ll instruct the automapper to use fields instead of properties.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class AppAutomappingCfg : DefaultAutomappingConfiguration
{
  public override bool ShouldMap(Member member)
  {
    return member.IsPrivate &amp;amp;&amp;amp; member.IsField;
  }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That&amp;#8217;s it, your automapper will now only map private fields. You&amp;#8217;re obviously fully capable of making your own rules up for what fields should be mapped. You could use a combination of fields and properties, only private fields, fields with certain attributes, etc&amp;#8230; It&amp;#8217;s up to you.&lt;/p&gt;</content>
  </entry>

  <entry>
    <title>ComponentMap (1.1 Feature Focus)</title>
    <link href="http://fluentnhibernate.org/blog/blog/2010/05/23/feature-focus-componentmap.html" />
    <updated>2010-05-23T00:00:00+00:00</updated>
    <id>http://fluentnhibernate.org/blog/blog/2010/05/23/feature-focus-componentmap</id>
    <content type="html">&lt;p&gt;In the 1.1 release we&amp;#8217;ve introduced a new mapping class to help clean up your mappings: the ComponentMap. The ComponentMap is extremely similar to ClassMap and ComponentMap, with the exception that it&amp;#8217;s for mapping components.&lt;/p&gt;

&lt;p&gt;When you have components that are cropping up in various places across your domain (Address, ContactDetails, Location, etc&amp;#8230;), it can be a nuisance to keep repeating the mappings for them. Some people have come up with some clever work arounds for this issue, but hopefully those won&amp;#8217;t be necessary now.&lt;/p&gt;

&lt;p&gt;Given a common component, we&amp;#8217;d map it with the ComponentMap like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class AddressMap : ComponentMap&amp;lt;Address&amp;gt;
{
  public AddressMap()
  {
    Map(x =&amp;gt; x.Street);
    Map(x =&amp;gt; x.City);
    Map(x =&amp;gt; x.State);
    Map(x =&amp;gt; x.PostalCode);
  }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then in your ClassMaps or SubclassMaps you just use the bodyless &lt;code&gt;Component&lt;/code&gt; method, which indicates to Fluent NHibernate that it should resolve the actual mapping for the component externally.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Component(x =&amp;gt; x.Address);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Any place in your domain where you use the above address will receive a copy of the mapping as defined in &lt;code&gt;AddressMap&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you require a prefix for your component columns, you can use the &lt;code&gt;ColumnPrefix&lt;/code&gt; method from the &lt;code&gt;Component&lt;/code&gt; method.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Component(x =&amp;gt; x.WorkAddress)
  .ColumnPrefix(&amp;quot;{property}_&amp;quot;);&lt;/code&gt;&lt;/pre&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: as with &lt;code&gt;SubclassMap&lt;/code&gt;, &lt;code&gt;ComponentMap&lt;/code&gt; isn&amp;#8217;t (as yet) compatible with the automapper. If you&amp;#8217;re using the automapper then you&amp;#8217;re better off using the &lt;code&gt;IsComponent&lt;/code&gt; configuration option.&lt;/p&gt;
&lt;/blockquote&gt;</content>
  </entry>

  <entry>
    <title>Automapping Configuration (1.1 Feature Focus)</title>
    <link href="http://fluentnhibernate.org/blog/blog/2010/05/23/feature-focus-automapping.html" />
    <updated>2010-05-23T00:00:00+00:00</updated>
    <id>http://fluentnhibernate.org/blog/blog/2010/05/23/feature-focus-automapping</id>
    <content type="html">&lt;p&gt;Automapping is conventional. It&amp;#8217;s great when those conventions match up with your own, but how often is that in reality? Nearly everybody needs to configure the automapper to some degree. Some more than others.&lt;/p&gt;

&lt;p&gt;Does your automapping configuration look anything like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;AutoMap.AssemblyOf&amp;lt;Person&amp;gt;()
  .Where(x =&amp;gt; x.Namespace.EndsWith(&amp;quot;Domain&amp;quot;))
  .IgnoreBase&amp;lt;EntityBase&amp;gt;()
  .Setup(cfg =&amp;gt;
  {
    cfg.FindIdentity = member =&amp;gt; member.Name == &amp;quot;EntityId&amp;quot;;
    cfg.IsDiscriminated = type =&amp;gt; type == typeof(Person);
    cfg.IsComponentType = type =&amp;gt; type.In(typeof(Address), typeof(ContactDetails));
    cfg.AbstractClassIsLayerSupertype = type =&amp;gt; type == typeof(Client);
  });&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ok, so that&amp;#8217;s a pretty big example. Not everyone&amp;#8217;s is going to look like that, but they do exist. It&amp;#8217;s a bit bloated? How about when you also put it in the context of your overall configuration?&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Fluently.Configure()
  .Database(SQLiteConfiguration.Standard.InMemory())
  .Mappings(m =&amp;gt;
  {
    m.FluentMappings.AddFromAssemblyOf&amp;lt;Person&amp;gt;();
    
    m.AutoMappings.Add(
      AutoMap.AssemblyOf&amp;lt;Person&amp;gt;()
        .Where(x =&amp;gt; x.Namespace.EndsWith(&amp;quot;Domain&amp;quot;))
        .IgnoreBase&amp;lt;EntityBase&amp;gt;()
        .Setup(cfg =&amp;gt;
        {
          cfg.FindIdentity = member =&amp;gt; member.Name == &amp;quot;EntityId&amp;quot;;
          cfg.IsDiscriminated = type =&amp;gt; type == typeof(Person);
          cfg.IsComponentType = type =&amp;gt; type.In(typeof(Address), typeof(ContactDetails));
          cfg.AbstractClassIsLayerSupertype = type =&amp;gt; type == typeof(Client);
        });
    );
  })
  .BuildSessionFactory();&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That&amp;#8217;s looking even messier now and, more importantly, a lot more difficult to mentally parse how the automapping is being configured. It&amp;#8217;s a big lump of method chaining mess.&lt;/p&gt;

&lt;p&gt;The changes that we&amp;#8217;ve made for the 1.1 release have introduced the concept of a configuration object for the automapper. Basically, it&amp;#8217;s the contents of the Setup method combined with the Where clause, extracted into a separate object. This change greatly reduces the noise in your configuration, gives you a known location for your automapping configuration (rather than having to dig around in your NHibernate session manager code), and increases your ability to replace and inject different configurations.&lt;/p&gt;

&lt;p&gt;Lets take a look at how the above is done in 1.1. We&amp;#8217;ll start with just the automapping configuration.&lt;/p&gt;

&lt;p&gt;The automapping configuration is based on implementing the IAutomappingConfiguration interface; this interface contains several methods that the automapper uses to know how to map your domain. Fear not though, you don&amp;#8217;t need to implement all these methods yourself (unless you want to). There&amp;#8217;s a DefaultAutomappingConfiguration class which is pre-configured with all the automapping defaults; you can derive from that class and just override whatever options you choose.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class AppAutomappingCfg : DefaultAutomappingConfiguration
{
  IEnumerable&amp;lt;Type&amp;gt; ignoredTypes = new[] {
    typeof(EntityBase)
  };

  public override bool ShouldMap(Type type)
  {
    if (ignoredTypes.Contains(type))
      return false;

    return type.Namespace.EndsWith(&amp;quot;Domain&amp;quot;);
  }
  
  public override bool IsDiscriminated(Type type)
  {
    return type == typeof(Person);
  }
  
  public override bool IsComponent(Type type)
  {
    return type.In(typeof(Address), typeof(ContactDetails));
  }
  
  public override bool AbstractClassIsLayerSupertype(Type type)
  {
    return type == tyepof(Client);
  }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That&amp;#8217;s our application&amp;#8217;s automapping configuration. It&amp;#8217;s pretty self explanatory really; the only method that might be unfamiliar is &lt;code&gt;ShouldMap(Type)&lt;/code&gt;, and this is simply a replacement for the &lt;code&gt;Where&lt;/code&gt; method. You can see in the &lt;code&gt;ShouldMap&lt;/code&gt; method we&amp;#8217;ve also got a &lt;code&gt;Contains&lt;/code&gt; call on a collection, this is an example of how you could roll the &lt;code&gt;IgnoreBase&lt;/code&gt; usage into your configuration; however, this is not required and you are still free to use &lt;code&gt;IgnoreBase&lt;/code&gt; if you prefer.&lt;/p&gt;

&lt;p&gt;To utilise this new configuration we need to modify our original &lt;code&gt;AutoMap&lt;/code&gt; call:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;AutoMap.AssemblyOf&amp;lt;Person&amp;gt;(new AppAutomappingCfg());&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That&amp;#8217;s all there is to our automapping call now, everything&amp;#8217;s incorporated in the configuration. Adding a little context, here&amp;#8217;s how it now looks in the whole configuration:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Fluently.Configure()
  .Database(SQLiteConfiguration.Standard.InMemory())
  .Mappings(m =&amp;gt;
  {
    m.FluentMappings.AddFromAssemblyOf&amp;lt;Person&amp;gt;();
    
    m.AutoMappings.Add(
      AutoMap.AssemblyOf&amp;lt;Person&amp;gt;(new AppAutomappingCfg())
    );
  })
  .BuildSessionFactory();&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Much tidier!&lt;/p&gt;</content>
  </entry>

  <entry>
    <title>Fluent NHibernate 1.1 Released</title>
    <link href="http://fluentnhibernate.org/blog/blog/2010/05/23/1.1-release.html" />
    <updated>2010-05-23T00:00:00+00:00</updated>
    <id>http://fluentnhibernate.org/blog/blog/2010/05/23/1.1-release</id>
    <content type="html">&lt;p&gt;It&amp;#8217;s been a long time coming, but here it is: &lt;a href='/downloads/releases/fluentnhibernate-1.1.zip'&gt;Fluent NHibernate 1.1&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The primary purpose of this release is to get everyone up-to-date and off the master branch. It comprises of over 200 commits, many bugfixes, and several new features.&lt;/p&gt;

&lt;p&gt;You can read the release notes over on the wiki: &lt;a href='http://wiki.fluentnhibernate.org/Release_notes_1.1'&gt;1.1 release notes&lt;/a&gt;, and an &lt;a href='http://wiki.fluentnhibernate.org/Release_1.1_upgrade_guide'&gt;upgrade guide from 1.0RTM&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve put together a few posts highlighting a few of the new features that&amp;#8217;ve been slipped into this release.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='/blog/2010/05/23/feature-focus-automapping.html'&gt;Automapping Configuration&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='/blog/2010/05/23/feature-focus-fields.html'&gt;Field support&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='/blog/2010/05/23/feature-focus-componentmap.html'&gt;ComponentMap&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In keeping with our dependency policy, we&amp;#8217;ve upgraded to the latest NHibernate release (2.1.2GA). Support for 3.0 will be added when a GA is available.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;d like to personally thank the Fluent NHibernate team for all their hard work, as well as the huge ammount of community support we&amp;#8217;ve received. Make sure to check out the &lt;a href='http://fluentnhibernate.org'&gt;front page&lt;/a&gt; of the Fluent NHibernate website to see the full list of people who&amp;#8217;ve contributed.&lt;/p&gt;</content>
  </entry>


</feed>

